Compare commits

..

10 Commits

Author SHA1 Message Date
Lennart Poettering 0289b4ec69
Merge pull request #15785 from poettering/pam-sudo-fixes-part1
some simple PAM fixes split out of #15742
2020-05-12 15:54:42 +02:00
Zbigniew Jędrzejewski-Szmek cd8fdc2c73
Merge pull request #15789 from poettering/homed-bus-api
man: document homed bus API
2020-05-12 11:42:40 +02:00
Lennart Poettering 3d9237d666 update TODO 2020-05-12 11:10:34 +02:00
Lennart Poettering 45c5fa253a pam_systemd: also print debug lines when ending a session 2020-05-12 11:10:30 +02:00
Lennart Poettering 3400bc866d pam_systemd: drop unused uid argument from export_legacy_dbus_address() 2020-05-12 11:10:27 +02:00
Lennart Poettering da4340fd43 pam_systemd_home: use correct macro for converting ptr to fd 2020-05-12 11:10:10 +02:00
Lennart Poettering 2dffb32309 man: document homed D-Bus API 2020-05-12 11:07:01 +02:00
Lennart Poettering 55842c7326 homed: fix parameter names on D-Bus methods
These arguments contain UserRecord structures serialized to JSON,
however only the "secret" part of it, not a whole user record. We do
this since the secret part is conceptually part of the user record and
in some contexts we need a user record in full with both secret and
non-secret part, and in others just the secret and in other just the
non-secret part, but we want to keep this in memory in the same logic.

Hence, let's rename the arguments where we expect a user record
consisting only of the secret part to "secret".
2020-05-12 11:06:46 +02:00
Lennart Poettering 671fee1873 man: run man/update-dbus-docs again 2020-05-12 11:06:28 +02:00
Lennart Poettering 9e45fb09bf netlink: port to recvmsg_safe()
This also makes sure the control buffer is properly aligned. This
matters, as otherwise the control buffer might not be aligned and the
cmsg buffer counting might be off. The incorrect alignment is becoming
visible by using recvmsg_safe() as we suddenly notice the MSG_CTRUNC bit
set because of this.

That said, apparently this isn't enough to make this work on all
kernels. Since I couldn't figure this out, we now add 1K to the buffer
to be sure. We do this once already, also for a pktinfo structure
(though an IPv4/IPv6) one. I am puzzled by this, but this shouldn't
matter much. it works locally just fine, except for those ubuntu CI
kernels...

While we are at it, make some other changes too, to simplify and
modernize the function.
2020-05-12 10:47:06 +02:00
10 changed files with 339 additions and 158 deletions

3
TODO
View File

@ -22,6 +22,9 @@ Janitorial Clean-ups:
Features: Features:
* move our systemd-user PAM snippet to /usr/, which PAM appears to support
these days
* nspawn: support time namespaces * nspawn: support time namespaces
* pid1: Move to tracking of main pid/control pid of units per pidfd * pid1: Move to tracking of main pid/control pid of units per pidfd

View File

@ -23,8 +23,7 @@
<refsect1> <refsect1>
<title>Introduction</title> <title>Introduction</title>
<para> <para><citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>
is a system service which may be used to to create, remove, change or inspect home areas. This page is a system service which may be used to to create, remove, change or inspect home areas. This page
describes the D-Bus interface. describes the D-Bus interface.
</para> </para>
@ -65,30 +64,30 @@ node /org/freedesktop/home1 {
out o bus_path); out o bus_path);
ListHomes(out a(susussso) home_areas); ListHomes(out a(susussso) home_areas);
ActivateHome(in s user_name, ActivateHome(in s user_name,
in s user_record); in s secret);
DeactivateHome(in s user_name); DeactivateHome(in s user_name);
RegisterHome(in s home_record); RegisterHome(in s user_record);
UnregisterHome(in s user_name); UnregisterHome(in s user_name);
CreateHome(in s home_record); CreateHome(in s user_record);
RealizeHome(in s user_name, RealizeHome(in s user_name,
in s user_record); in s secret);
RemoveHome(in s user_name); RemoveHome(in s user_name);
FixateHome(in s user_name, FixateHome(in s user_name,
in s user_record); in s secret);
AuthenticateHome(in s user_name, AuthenticateHome(in s user_name,
in s user_record); in s secret);
UpdateHome(in s user_record); UpdateHome(in s user_record);
ResizeHome(in s user_name, ResizeHome(in s user_name,
in t size, in t size,
in s user_record); in s secret);
ChangePasswordHome(in s user_name, ChangePasswordHome(in s user_name,
in s new_user_record, in s new_secret,
in s old_user_record); in s old_secret);
LockHome(in s user_name); LockHome(in s user_name);
UnlockHome(in s user_name, UnlockHome(in s user_name,
in s user_record); in s secret);
AcquireHome(in s user_name, AcquireHome(in s user_name,
in s user_record, in s secret,
in b please_suspend, in b please_suspend,
out h send_fd); out h send_fd);
RefHome(in s user_name, RefHome(in s user_name,
@ -105,54 +104,6 @@ node /org/freedesktop/home1 {
}; };
</programlisting> </programlisting>
<!--method GetHomeByName is not documented!-->
<!--method GetHomeByUID is not documented!-->
<!--method GetUserRecordByName is not documented!-->
<!--method GetUserRecordByUID is not documented!-->
<!--method ListHomes is not documented!-->
<!--method ActivateHome is not documented!-->
<!--method DeactivateHome is not documented!-->
<!--method RegisterHome is not documented!-->
<!--method UnregisterHome is not documented!-->
<!--method CreateHome is not documented!-->
<!--method RealizeHome is not documented!-->
<!--method RemoveHome is not documented!-->
<!--method FixateHome is not documented!-->
<!--method AuthenticateHome is not documented!-->
<!--method UpdateHome is not documented!-->
<!--method ResizeHome is not documented!-->
<!--method ChangePasswordHome is not documented!-->
<!--method LockHome is not documented!-->
<!--method UnlockHome is not documented!-->
<!--method AcquireHome is not documented!-->
<!--method RefHome is not documented!-->
<!--method ReleaseHome is not documented!-->
<!--method LockAllHomes is not documented!-->
<!--property AutoLogin is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Manager"/> <variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.home1.Manager"/>
@ -212,13 +163,193 @@ node /org/freedesktop/home1 {
<refsect2> <refsect2>
<title>Methods</title> <title>Methods</title>
<para>...</para> <para><function>GetHomeByName()</function> returns basic user information (a minimal subset of the full
user record), provided a user name. The information supplied more or less matches what
<citerefentry><refentrytitle>getpwnam</refentrytitle><manvolnum>3</manvolnum></citerefentry> returns:
the numeric UID and GID, the real name, home directory and shell. In addition it returns a state
identifier describing the state the user's home directory is in, as well as a bus path referring to the
bus object encapsulating the user record and home directory. This object implements the
<classname>org.freedesktop.home1.Home</classname> interface documented below.</para>
<para><function>GetHomeByUID()</function> is similar to <function>GetHomeByName()</function> but
acquires the information based on the numeric UID of the user.</para>
<para><function>GetUserRecordByName()</function> is also similar to
<function>GetHomeByName()</function> but returns the full JSON user record data instead of the broken
down records. An additional returned boolean indicates whether the record is complete or not. A record
is considered complete when its <literal>privileged</literal> section is included, and incomplete if it
was removed (see <ulink url="https://systemd.io/USER_RECORD">JSON User Records</ulink> for details
about the various sections of a user record). Generally, only privileged clients and clients running
under the identity of the user itself get access to the <literal>privileged</literal> section and will
thus see complete records.</para>
<para><function>GetUserRecordByUID()</function> is similar to <function>GetUserRecordByName()</function>
but returns the user record matching the specified numeric UID.</para>
<para><function>ListHomes()</function> returns an array of all locally managed users. The array
contains the same fields <function>GetHomeByName()</function> returns: user name, numeric UID, state,
numeric GID, real name, home directory, shell and bus path of the matching bus object.</para>
<para><function>ActivateHome()</function> activates (i.e. mounts) the home directory of the specified
user. The second argument shall contain a user record consisting only of a <literal>secret</literal>
section (all other sections should be stripped, see <ulink url="https://systemd.io/USER_RECORD">JSON
User Records</ulink> for details), and should contain only the secret credentials necessary for
unlocking the home directory. Typically a client would invoke this function first with an entirely
empty record (which is possibly sufficient if single-factor authentication with a plugged-in security
token is configured), and would then retry with a record populated with more information, depending on
the returned error code, in case more credentials are necessary. This function is synchronous and
returns only after the home directory was fully activated (or the operation failed), which might take
some time. Clients must be prepared for that, and typically should extend the D-Bus method call
time-out accordingly. This method is equivalent to the <function>Activate()</function> method on the
<classname>org.freedesktop.home1.Home</classname> interface documented below, but may be called on the
manager object and takes a user name as additional argument, instead.</para>
<para><function>DeactivateHome()</function> deactivates (i.e. unmounts) the home directory of the
specified user. It is equivalent to the <function>Deactivate()</function> method on the
<classname>org.freedesktop.home1.Home</classname> interface documented below.</para>
<para><function>RegisterHome()</function> registers a new home directory locally. It receives the JSON
user record as only argument (which typically excludes the <literal>secret</literal>
section). Registering a home directory just makes the user record known to the system, it does not
create a home directory or such (which is expected to exist already, or created later). This operation
is useful to register home directories locally that are not located where
<filename>systemd-homed.service</filename> would find them automatically.</para>
<para><function>UnregisterHome()</function> unregisters an existing home directory. It takes a user
name as argument and undoes what <function>RegisterHome()</function> does. It does not attempt to
remove the home directory itself, it just unregisters it with the local system. Note that if the home
directory is placed where <filename>systemd-homed.service</filename> looks for home directories anyway
this call will only undo fixation (see below), but the record will remain known to
<filename>systemd-homed.service</filename> and be listed among known records. Since the user record is
embedded into the home directory this operation generally does not discard data belonging to the user
or their record. This method is equivalent to
<function>Unregister()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>CreateHome()</function> registers and creates a new home directory. This takes a fully
specified JSON user record as argument (including the <literal>secret</literal> section. This registers
the user record locally and creates a home directory matching it, depending on the settings specified
in the record in combination with local configuration.</para>
<para><function>RealizeHome()</function> creates a home directory whose user record is already
registered locally. This takes a user name plus a user record consisting only of the
<literal>secret</literal> section. Invoking <function>RegisterHome()</function> followed by
<function>RealizeHome()</function> is mostly equivalent to calling <function>CreateHome()</function>,
except that the latter combines the two in atomic fashion. This method is equivalent to
<function>Realize()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>RemoveHome()</function> unregisters a user record locally, and removes the home
directory belonging to it, if it is accessible. It takes a user name as argument. This method is equivalent to
<function>Remove()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>FixateHome()</function> <literal>fixates</literal> an automatically discovered home
directory. <filename>systemd-homed.service</filename> automatically discovers home directories dropped
in our plugged in and adds them to the runtime list of user records it manages. A user record
discovered that way may be <literal>fixated</literal>, in which case it is copied out of the home
directory, onto persistent storage, to fixate the UID/GID assignment of the record, and extract
additional (typically previously encrypted) user record data from the home directory. A home directory
mus be fixated before it can be logged into. This method call takes a user name and a JSON user record
consisting only of the <literal>secret</literal> section as argument. This method is equivalent to
<function>Fixate()</function> on the <classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>AuthenticateHome()</function> checks passwords or other authentication credentials
associated with the home directory. It takes a user name and a JSON user record consisting only of the
<literal>secret</literal> section as argument. Note that many of the other method calls authenticate
the user first, in order to execute some other operation. This method call only authenticates and
executes no further operation. Like <function>ActivateHome()</function> it is usually first invoked
with an empty JSON user record, which is then populated for subsequent tries with additional
authentication data supplied. This method is equivalent to
<function>Authenticate()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>UpdateHome()</function> updates a locally registered user record. Takes a fully
specified JSON user record as argument (including the <literal>secret</literal> section). A user with a
matching name and realm must be registered locally already, and the last change timestamp of the newly
supplied record must be newer than the previously existing user record. Note this operation updates the
user record only, it does not propagate passwords/authentication tokens from the user record to the
storage back-end, or resizes the storage back-end. Typically a home directory is first updated, and then
the password of the underlying storage updated using <function>ChangePasswordHome()</function> as well
as the storage resized using <function>ResizeHome()</function>. This method is equivalent to
<function>Update()</function> on the <classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>ResizeHome()</function> resizes the storage associated with a user record. Takes a user
name, a disk size in bytes and a user record consisting only of the <literal>secret</literal> section
as argument. If the size is specified as <constant>UINT64_MAX</constant> the storage is resized to the
size already specified in the user record. Typically, if the user record is updated using
<function>UpdateHome()</function> above this is used to propagate the size configured there-in down to
the underlying storage back-end. This method is equivalent to
<function>Resize()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>ChangePasswordHome()</function> changes the passwords/authentication tokens of a home
directory. Takes a user name, and two JSON user record objects, each consisting only of the
<literal>secret</literal> section, for the old and for the new passwords/authentication tokens. If the
user record with the new passwords/authentication token data is specified as empty the existing user
record's settings are propagated down to the home directory storage. This is typically used after a
user record is updated using <function>UpdateHome()</function> in order to propagate the
secrets/authentication tokens down to the storage. This method is equivalent to
<function>ChangePassword()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>LockHome()</function> temporarily suspends access to a home directory, flushing out any
cryptographic keys from memory. This is only supported on some back-ends, and usually done during system
suspend, in order to effectively secure home directories while the system is sleeping. Takes a user
name as single argument. If an application attempts to access a home directory while it is locked it
will typically freeze until the home directory is unlocked again. This method is equivalent to
<function>Lock()</function> on the <classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>UnlockHome()</function> undoes the effect of <function>LockHome()</function>. Takes a
user name and a user record consisting only of the <literal>secret</literal> section as arguments. This
method is equivalent to <function>Unlock()</function> on the
<classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>AcquireHome()</function> activates or unlocks a home directory in a reference counted
mode of operation. Takes a user name and user record consisting only of <literal>secret</literal>
section as argument. If the home directory is not active yet, it is activated. If it is currently
locked it is unlocked. After completion a reference to the activation/unlocking of the home directory
is returned via a file descriptor. When the last client which acquired such a file descriptor closes it
the home directory is automatically deactivated again. This method is typically invoked when a user
logs in, and the file descriptor is held until the user logs out again, thus ensuring the user's home
directory can be unmounted automatically again in a robust fashion, when the user logs out. The third
argument is a boolean which indicates whether the client invoking the call is able to automatically
re-authenticate when the system comes back from suspending. It should be set by all clients that
implement a secure lock screen running outside of the user's context, that is brought up when the
system comes back from suspend and can be used to re-acquire the credentials to unlock the user's home
directory. If a home directory has at least one client with an open reference to the home directory
that does not support this it is not suspended automatically at system suspend, otherwise it is. This
method is equivalent to <function>Acquire()</function> on the
<classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>RefHome()</function> is similar to <function>AcquireHome()</function> but takes no user
record with <literal>secret</literal> section, i.e. will take an additional reference to an already
activated/unlocked home directory without attempting to activate/unlock it itself. It will fail if the
home directory is not already activated. This method is equivalent to
<function>Ref()</function> on the <classname>org.freedesktop.home1.Home</classname>
interface.</para>
<para><function>ReleaseHome()</function> releases a home directory again, if all file descriptors
referencing it are already closed, that where acquired through <function>AcquireHome()</function> or
<function>RefHome()</function>. Note that this call does not actually cause the deactivation of the
home directory (which happens automatically when the last referencing file descriptor is closed), but
is simply a synchronization mechanism that allows delaying of the user session's termination until any
triggered deactivation is completed. This method is equivalent to <function>Release()</function> on the
<classname>org.freedesktop.home1.Home</classname> interface.</para>
<para><function>LockAllHomes()</function> locks all active home directories that only have references
that opted into automatic suspending during system suspend. This is usually invoked automatically
shortly before system suspend.</para>
</refsect2> </refsect2>
<refsect2> <refsect2>
<title>Signals</title> <title>Properties</title>
<para>...</para> <para><varname>AutoLogin</varname> exposes an array of structures consisting of user name, seat name
and object path of an home directory object. All locally managed users that have the
<literal>autoLogin</literal> field set are listed here, with the seat name they are associated with. A
display manager may watch this property and pre-fill the login screen with the users exposed this
way.</para>
</refsect2> </refsect2>
</refsect1> </refsect1>
@ -229,21 +360,21 @@ node /org/freedesktop/home1 {
node /org/freedesktop/home1/home { node /org/freedesktop/home1/home {
interface org.freedesktop.home1.Home { interface org.freedesktop.home1.Home {
methods: methods:
Activate(in s user_record); Activate(in s secret);
Deactivate(); Deactivate();
Unregister(); Unregister();
Realize(in s user_record); Realize(in s secret);
Remove(); Remove();
Fixate(in s user_record); Fixate(in s secret);
Authenticate(in s user_record); Authenticate(in s secret);
Update(in s user_record); Update(in s user_record);
Resize(in t size, Resize(in t size,
in s user_record); in s secret);
ChangePassword(in s new_user_record, ChangePassword(in s new_secret,
in s old_user_record); in s old_secret);
Lock(); Lock();
Unlock(in s user_record); Unlock(in s secret);
Acquire(in s user_record, Acquire(in s secret,
in b please_suspend, in b please_suspend,
out h send_fd); out h send_fd);
Ref(in b please_suspend, Ref(in b please_suspend,
@ -266,46 +397,6 @@ node /org/freedesktop/home1/home {
}; };
</programlisting> </programlisting>
<!--method Activate is not documented!-->
<!--method Deactivate is not documented!-->
<!--method Unregister is not documented!-->
<!--method Realize is not documented!-->
<!--method Remove is not documented!-->
<!--method Fixate is not documented!-->
<!--method Authenticate is not documented!-->
<!--method Update is not documented!-->
<!--method Resize is not documented!-->
<!--method ChangePassword is not documented!-->
<!--method Lock is not documented!-->
<!--method Unlock is not documented!-->
<!--method Acquire is not documented!-->
<!--method Ref is not documented!-->
<!--method Release is not documented!-->
<!--property UserName is not documented!-->
<!--property UID is not documented!-->
<!--property UnixRecord is not documented!-->
<!--property State is not documented!-->
<!--property UserRecord is not documented!-->
<!--Autogenerated cross-references for systemd.directives, do not edit--> <!--Autogenerated cross-references for systemd.directives, do not edit-->
<variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.DBus.ObjectManager"/> <variablelist class="dbus-interface" generated="True" extra-ref="org.freedesktop.DBus.ObjectManager"/>
@ -358,7 +449,39 @@ node /org/freedesktop/home1/home {
<!--End of Autogenerated section--> <!--End of Autogenerated section-->
</refsect1> <refsect2>
<title>Methods</title>
<para><function>Activate()</function>, <function>Deactivate()</function>,
<function>Unregister()</function>, <function>Realize()</function>, <function>Remove()</function>,
<function>Fixate()</function>, <function>Authenticate()</function>, <function>Update()</function>,
<function>Resize()</function>, <function>ChangePassword()</function>, <function>Lock()</function>,
<function>Unlock()</function>, <function>Acquire()</function>, <function>Ref()</function>,
<function>Release()</function> operate like their matching counterparts on the
<classname>org.freedesktop.home1.Manager</classname> interface (see above). The main difference is that
they are methods of the home directory objects, and hence carry no additional user name
parameter. Which of the two flavors of methods to call depends on the handles to the user known on the
client side: if only the user name is known, it's preferable to use the methods on the manager object
since they operate with user names only. If however the home object path was already acquired some way
it is preferable to operate on the <classname>org.freedesktop.home1.Home</classname> objects
instead.</para>
</refsect2>
<refsect2>
<title>Properties</title>
<para><varname>UserName</varname> contains the user name of the user account/home directory.</para>
<para><varname>UID</varname> contains the numeric UNIX UID of the user account.</para>
<para><varname>UnixRecord</varname> contains a structure encapsulating the six fields a
<structname>struct passwd</structname> typically contains (the password field is suppressed).</para>
<para><varname>State</varname> exposes the current state home the home directory.</para>
<para><varname>UserRecord</varname> contains the full JSON user record string of the user account.</para>
</refsect2>
</refsect1>
<refsect1> <refsect1>
<title>Versioning</title> <title>Versioning</title>
@ -366,4 +489,14 @@ node /org/freedesktop/home1/home {
<para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html"> <para>These D-Bus interfaces follow <ulink url="http://0pointer.de/blog/projects/versioning-dbus.html">
the usual interface versioning guidelines</ulink>.</para> the usual interface versioning guidelines</ulink>.</para>
</refsect1> </refsect1>
<refsect1>
<title>See Also</title>
<para>
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>systemd-homed.service</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>
</para>
</refsect1>
</refentry> </refentry>

View File

@ -110,6 +110,8 @@ node /org/freedesktop/systemd1 {
in i signal); in i signal);
CleanUnit(in s name, CleanUnit(in s name,
in as mask); in as mask);
FreezeUnit(in s name);
ThawUnit(in s name);
ResetFailedUnit(in s name); ResetFailedUnit(in s name);
SetUnitProperties(in s name, SetUnitProperties(in s name,
in b runtime, in b runtime,
@ -485,6 +487,10 @@ node /org/freedesktop/systemd1 {
<!--method CleanUnit is not documented!--> <!--method CleanUnit is not documented!-->
<!--method FreezeUnit is not documented!-->
<!--method ThawUnit is not documented!-->
<!--method RefUnit is not documented!--> <!--method RefUnit is not documented!-->
<!--method UnrefUnit is not documented!--> <!--method UnrefUnit is not documented!-->
@ -743,6 +749,10 @@ node /org/freedesktop/systemd1 {
<variablelist class="dbus-method" generated="True" extra-ref="CleanUnit()"/> <variablelist class="dbus-method" generated="True" extra-ref="CleanUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="FreezeUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ThawUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="ResetFailedUnit()"/> <variablelist class="dbus-method" generated="True" extra-ref="ResetFailedUnit()"/>
<variablelist class="dbus-method" generated="True" extra-ref="SetUnitProperties()"/> <variablelist class="dbus-method" generated="True" extra-ref="SetUnitProperties()"/>
@ -1514,6 +1524,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
Ref(); Ref();
Unref(); Unref();
Clean(in as mask); Clean(in as mask);
Freeze();
Thaw();
properties: properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s Id = '...'; readonly s Id = '...';
@ -1570,6 +1582,7 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s LoadState = '...'; readonly s LoadState = '...';
readonly s ActiveState = '...'; readonly s ActiveState = '...';
readonly s FreezerState = '...';
readonly s SubState = '...'; readonly s SubState = '...';
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s FragmentPath = '...'; readonly s FragmentPath = '...';
@ -1601,6 +1614,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
readonly b CanIsolate = ...; readonly b CanIsolate = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly as CanClean = ['...', ...]; readonly as CanClean = ['...', ...];
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b CanFreeze = ...;
readonly (uo) Job = ...; readonly (uo) Job = ...;
@org.freedesktop.DBus.Property.EmitsChangedSignal("const") @org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly b StopWhenUnneeded = ...; readonly b StopWhenUnneeded = ...;
@ -1678,6 +1693,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--method Clean is not documented!--> <!--method Clean is not documented!-->
<!--method Freeze is not documented!-->
<!--method Thaw is not documented!-->
<!--property PartOf is not documented!--> <!--property PartOf is not documented!-->
<!--property RequisiteOf is not documented!--> <!--property RequisiteOf is not documented!-->
@ -1688,6 +1707,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--property JoinsNamespaceOf is not documented!--> <!--property JoinsNamespaceOf is not documented!-->
<!--property FreezerState is not documented!-->
<!--property DropInPaths is not documented!--> <!--property DropInPaths is not documented!-->
<!--property UnitFilePreset is not documented!--> <!--property UnitFilePreset is not documented!-->
@ -1698,6 +1719,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<!--property CanClean is not documented!--> <!--property CanClean is not documented!-->
<!--property CanFreeze is not documented!-->
<!--property OnFailureJobMode is not documented!--> <!--property OnFailureJobMode is not documented!-->
<!--property JobRunningTimeoutUSec is not documented!--> <!--property JobRunningTimeoutUSec is not documented!-->
@ -1770,6 +1793,10 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<variablelist class="dbus-method" generated="True" extra-ref="Clean()"/> <variablelist class="dbus-method" generated="True" extra-ref="Clean()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Freeze()"/>
<variablelist class="dbus-method" generated="True" extra-ref="Thaw()"/>
<variablelist class="dbus-property" generated="True" extra-ref="Id"/> <variablelist class="dbus-property" generated="True" extra-ref="Id"/>
<variablelist class="dbus-property" generated="True" extra-ref="Names"/> <variablelist class="dbus-property" generated="True" extra-ref="Names"/>
@ -1826,6 +1853,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<variablelist class="dbus-property" generated="True" extra-ref="ActiveState"/> <variablelist class="dbus-property" generated="True" extra-ref="ActiveState"/>
<variablelist class="dbus-property" generated="True" extra-ref="FreezerState"/>
<variablelist class="dbus-property" generated="True" extra-ref="SubState"/> <variablelist class="dbus-property" generated="True" extra-ref="SubState"/>
<variablelist class="dbus-property" generated="True" extra-ref="FragmentPath"/> <variablelist class="dbus-property" generated="True" extra-ref="FragmentPath"/>
@ -1868,6 +1897,8 @@ node /org/freedesktop/systemd1/unit/avahi_2ddaemon_2eservice {
<variablelist class="dbus-property" generated="True" extra-ref="CanClean"/> <variablelist class="dbus-property" generated="True" extra-ref="CanClean"/>
<variablelist class="dbus-property" generated="True" extra-ref="CanFreeze"/>
<variablelist class="dbus-property" generated="True" extra-ref="Job"/> <variablelist class="dbus-property" generated="True" extra-ref="Job"/>
<variablelist class="dbus-property" generated="True" extra-ref="StopWhenUnneeded"/> <variablelist class="dbus-property" generated="True" extra-ref="StopWhenUnneeded"/>

View File

@ -103,7 +103,8 @@
<citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>, <citerefentry><refentrytitle>homed.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
<citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>, <citerefentry><refentrytitle>homectl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>pam_systemd_home</refentrytitle><manvolnum>8</manvolnum></citerefentry>, <citerefentry><refentrytitle>pam_systemd_home</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
<citerefentry><refentrytitle>userdbctl</refentrytitle><manvolnum>1</manvolnum></citerefentry> <citerefentry><refentrytitle>userdbctl</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
<citerefentry><refentrytitle>org.freedesktop.home1</refentrytitle><manvolnum>5</manvolnum></citerefentry>
</para> </para>
</refsect1> </refsect1>
</refentry> </refentry>

View File

@ -798,7 +798,7 @@ const sd_bus_vtable home_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("Activate", SD_BUS_METHOD_WITH_NAMES("Activate",
"s", "s",
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_activate, bus_home_method_activate,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
@ -806,7 +806,7 @@ const sd_bus_vtable home_vtable[] = {
SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Realize", SD_BUS_METHOD_WITH_NAMES("Realize",
"s", "s",
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_realize, bus_home_method_realize,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -814,13 +814,13 @@ const sd_bus_vtable home_vtable[] = {
SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("Remove", NULL, NULL, bus_home_method_remove, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD_WITH_NAMES("Fixate", SD_BUS_METHOD_WITH_NAMES("Fixate",
"s", "s",
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_fixate, bus_home_method_fixate,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Authenticate", SD_BUS_METHOD_WITH_NAMES("Authenticate",
"s", "s",
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_authenticate, bus_home_method_authenticate,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -833,27 +833,27 @@ const sd_bus_vtable home_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("Resize", SD_BUS_METHOD_WITH_NAMES("Resize",
"ts", "ts",
SD_BUS_PARAM(size) SD_BUS_PARAM(size)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_resize, bus_home_method_resize,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("ChangePassword", SD_BUS_METHOD_WITH_NAMES("ChangePassword",
"ss", "ss",
SD_BUS_PARAM(new_user_record) SD_BUS_PARAM(new_secret)
SD_BUS_PARAM(old_user_record), SD_BUS_PARAM(old_secret),
NULL,, NULL,,
bus_home_method_change_password, bus_home_method_change_password,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0), SD_BUS_METHOD("Lock", NULL, NULL, bus_home_method_lock, 0),
SD_BUS_METHOD_WITH_NAMES("Unlock", SD_BUS_METHOD_WITH_NAMES("Unlock",
"s", "s",
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
bus_home_method_unlock, bus_home_method_unlock,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
SD_BUS_METHOD_WITH_NAMES("Acquire", SD_BUS_METHOD_WITH_NAMES("Acquire",
"sb", "sb",
SD_BUS_PARAM(user_record) SD_BUS_PARAM(secret)
SD_BUS_PARAM(please_suspend), SD_BUS_PARAM(please_suspend),
"h", "h",
SD_BUS_PARAM(send_fd), SD_BUS_PARAM(send_fd),

View File

@ -661,7 +661,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("ActivateHome", SD_BUS_METHOD_WITH_NAMES("ActivateHome",
"ss", "ss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_activate_home, method_activate_home,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
@ -675,7 +675,7 @@ static const sd_bus_vtable manager_vtable[] = {
/* Add the JSON record to homed, but don't create actual $HOME */ /* Add the JSON record to homed, but don't create actual $HOME */
SD_BUS_METHOD_WITH_NAMES("RegisterHome", SD_BUS_METHOD_WITH_NAMES("RegisterHome",
"s", "s",
SD_BUS_PARAM(home_record), SD_BUS_PARAM(user_record),
NULL,, NULL,,
method_register_home, method_register_home,
SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_VTABLE_UNPRIVILEGED),
@ -691,7 +691,7 @@ static const sd_bus_vtable manager_vtable[] = {
/* Add JSON record, and create $HOME for it */ /* Add JSON record, and create $HOME for it */
SD_BUS_METHOD_WITH_NAMES("CreateHome", SD_BUS_METHOD_WITH_NAMES("CreateHome",
"s", "s",
SD_BUS_PARAM(home_record), SD_BUS_PARAM(user_record),
NULL,, NULL,,
method_create_home, method_create_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -700,7 +700,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("RealizeHome", SD_BUS_METHOD_WITH_NAMES("RealizeHome",
"ss", "ss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_realize_home, method_realize_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -717,7 +717,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("FixateHome", SD_BUS_METHOD_WITH_NAMES("FixateHome",
"ss", "ss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_fixate_home, method_fixate_home,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
@ -726,7 +726,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("AuthenticateHome", SD_BUS_METHOD_WITH_NAMES("AuthenticateHome",
"ss", "ss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_authenticate_home, method_authenticate_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -743,7 +743,7 @@ static const sd_bus_vtable manager_vtable[] = {
"sts", "sts",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(size) SD_BUS_PARAM(size)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_resize_home, method_resize_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -751,8 +751,8 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("ChangePasswordHome", SD_BUS_METHOD_WITH_NAMES("ChangePasswordHome",
"sss", "sss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(new_user_record) SD_BUS_PARAM(new_secret)
SD_BUS_PARAM(old_user_record), SD_BUS_PARAM(old_secret),
NULL,, NULL,,
method_change_password_home, method_change_password_home,
SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE),
@ -769,7 +769,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("UnlockHome", SD_BUS_METHOD_WITH_NAMES("UnlockHome",
"ss", "ss",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record), SD_BUS_PARAM(secret),
NULL,, NULL,,
method_unlock_home, method_unlock_home,
SD_BUS_VTABLE_SENSITIVE), SD_BUS_VTABLE_SENSITIVE),
@ -784,7 +784,7 @@ static const sd_bus_vtable manager_vtable[] = {
SD_BUS_METHOD_WITH_NAMES("AcquireHome", SD_BUS_METHOD_WITH_NAMES("AcquireHome",
"ssb", "ssb",
SD_BUS_PARAM(user_name) SD_BUS_PARAM(user_name)
SD_BUS_PARAM(user_record) SD_BUS_PARAM(secret)
SD_BUS_PARAM(please_suspend), SD_BUS_PARAM(please_suspend),
"h", "h",
SD_BUS_PARAM(send_fd), SD_BUS_PARAM(send_fd),

View File

@ -411,7 +411,7 @@ static int acquire_home(
/* If we already have acquired the fd, let's shortcut this */ /* If we already have acquired the fd, let's shortcut this */
r = pam_get_data(handle, "systemd-home-fd", &home_fd_ptr); r = pam_get_data(handle, "systemd-home-fd", &home_fd_ptr);
if (r == PAM_SUCCESS && PTR_TO_INT(home_fd_ptr) >= 0) if (r == PAM_SUCCESS && PTR_TO_FD(home_fd_ptr) >= 0)
return PAM_SUCCESS; return PAM_SUCCESS;
r = pam_acquire_bus_connection(handle, &bus); r = pam_acquire_bus_connection(handle, &bus);

View File

@ -16,6 +16,10 @@
#include "socket-util.h" #include "socket-util.h"
#include "util.h" #include "util.h"
/* For some reason we need some extra cmsg space on some kernels. It's not clear why, and one of those days
* we need to track this down. See: https://github.com/systemd/systemd/pull/15457 */
#define EXTRA_CMSG_SPACE 1024
int socket_open(int family) { int socket_open(int family) {
int fd; int fd;
@ -240,30 +244,27 @@ int socket_write_message(sd_netlink *nl, sd_netlink_message *m) {
static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) { static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_group, bool peek) {
union sockaddr_union sender; union sockaddr_union sender;
uint8_t cmsg_buffer[CMSG_SPACE(sizeof(struct nl_pktinfo))]; CMSG_BUFFER_TYPE(CMSG_SPACE(sizeof(struct nl_pktinfo)) + EXTRA_CMSG_SPACE) control;
struct msghdr msg = { struct msghdr msg = {
.msg_iov = iov, .msg_iov = iov,
.msg_iovlen = 1, .msg_iovlen = 1,
.msg_name = &sender, .msg_name = &sender,
.msg_namelen = sizeof(sender), .msg_namelen = sizeof(sender),
.msg_control = cmsg_buffer, .msg_control = &control,
.msg_controllen = sizeof(cmsg_buffer), .msg_controllen = sizeof(control),
}; };
ssize_t n; ssize_t n;
assert(fd >= 0); assert(fd >= 0);
assert(iov); assert(iov);
n = recvmsg(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0)); n = recvmsg_safe(fd, &msg, MSG_TRUNC | (peek ? MSG_PEEK : 0));
if (n < 0) { if (n == -ENOBUFS)
/* no data */ return log_debug_errno(n, "rtnl: kernel receive buffer overrun");
if (errno == ENOBUFS) if (IN_SET(n, -EAGAIN, -EINTR))
log_debug("rtnl: kernel receive buffer overrun"); return 0;
else if (errno == EAGAIN) if (n < 0)
log_debug("rtnl: no data in socket"); return (int) n;
return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno;
}
if (sender.nl.nl_pid != 0) { if (sender.nl.nl_pid != 0) {
/* not from the kernel, ignore */ /* not from the kernel, ignore */
@ -271,20 +272,20 @@ static int socket_recv_message(int fd, struct iovec *iov, uint32_t *ret_mcast_gr
if (peek) { if (peek) {
/* drop the message */ /* drop the message */
n = recvmsg(fd, &msg, 0); n = recvmsg_safe(fd, &msg, 0);
if (n < 0) if (n < 0)
return IN_SET(errno, EAGAIN, EINTR) ? 0 : -errno; return (int) n;
} }
return 0; return 0;
} }
if (ret_mcast_group) { if (ret_mcast_group) {
struct cmsghdr *cmsg; struct nl_pktinfo *pi;
cmsg = cmsg_find(&msg, SOL_NETLINK, NETLINK_PKTINFO, CMSG_LEN(sizeof(struct nl_pktinfo))); pi = CMSG_FIND_DATA(&msg, SOL_NETLINK, NETLINK_PKTINFO, struct nl_pktinfo);
if (cmsg) if (pi)
*ret_mcast_group = ((struct nl_pktinfo*) CMSG_DATA(cmsg))->group; *ret_mcast_group = pi->group;
else else
*ret_mcast_group = 0; *ret_mcast_group = 0;
} }

View File

@ -280,7 +280,6 @@ static int get_seat_from_display(const char *display, const char **seat, uint32_
static int export_legacy_dbus_address( static int export_legacy_dbus_address(
pam_handle_t *handle, pam_handle_t *handle,
uid_t uid,
const char *runtime) { const char *runtime) {
const char *s; const char *s;
@ -681,7 +680,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
} }
} }
r = export_legacy_dbus_address(handle, ur->uid, rt); r = export_legacy_dbus_address(handle, rt);
if (r != PAM_SUCCESS) if (r != PAM_SUCCESS)
return r; return r;
@ -885,7 +884,7 @@ _public_ PAM_EXTERN int pam_sm_open_session(
return r; return r;
} }
r = export_legacy_dbus_address(handle, ur->uid, runtime_path); r = export_legacy_dbus_address(handle, runtime_path);
if (r != PAM_SUCCESS) if (r != PAM_SUCCESS)
return r; return r;
} }
@ -957,11 +956,23 @@ _public_ PAM_EXTERN int pam_sm_close_session(
int argc, const char **argv) { int argc, const char **argv) {
const void *existing = NULL; const void *existing = NULL;
bool debug = false;
const char *id; const char *id;
int r; int r;
assert(handle); assert(handle);
if (parse_argv(handle,
argc, argv,
NULL,
NULL,
NULL,
&debug) < 0)
return PAM_SESSION_ERR;
if (debug)
pam_syslog(handle, LOG_DEBUG, "pam-systemd shutting down");
/* Only release session if it wasn't pre-existing when we /* Only release session if it wasn't pre-existing when we
* tried to create it */ * tried to create it */
(void) pam_get_data(handle, "systemd.existing", &existing); (void) pam_get_data(handle, "systemd.existing", &existing);

View File

@ -165,6 +165,7 @@ void manager_verify_all(Manager *m);
DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free); DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_free);
/* For some reason we need some extra cmsg space on some kernels/archs. One of those days we ned to figure out why */
#define EXTRA_CMSG_SPACE 1024 #define EXTRA_CMSG_SPACE 1024
int manager_is_own_hostname(Manager *m, const char *name); int manager_is_own_hostname(Manager *m, const char *name);