Skip to content

Commit

Permalink
Merge pull request systemd#31841 from AdrianVovk/homed-trivial
Browse files Browse the repository at this point in the history
Small homed changes + revert
  • Loading branch information
yuwata authored Mar 19, 2024
2 parents 27e3e6a + 1f8aa84 commit 169b282
Show file tree
Hide file tree
Showing 8 changed files with 50 additions and 184 deletions.
59 changes: 19 additions & 40 deletions man/org.freedesktop.home1.xml
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,6 @@ node /org/freedesktop/home1 {
out h send_fd);
@org.freedesktop.systemd1.Privileged("true")
ReleaseHome(in s user_name);
InhibitSuspendHome(in s user_name,
out h send_fd);
@org.freedesktop.systemd1.Privileged("true")
LockAllHomes();
@org.freedesktop.systemd1.Privileged("true")
Expand Down Expand Up @@ -187,8 +185,6 @@ node /org/freedesktop/home1 {

<variablelist class="dbus-method" generated="True" extra-ref="ReleaseHome()"/>

<variablelist class="dbus-method" generated="True" extra-ref="InhibitSuspendHome()"/>

<variablelist class="dbus-method" generated="True" extra-ref="LockAllHomes()"/>

<variablelist class="dbus-method" generated="True" extra-ref="DeactivateAllHomes()"/>
Expand All @@ -208,7 +204,9 @@ node /org/freedesktop/home1 {
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>
<classname>org.freedesktop.home1.Home</classname> interface documented below. This method, and most others
in this interface that take user names, will try to use the caller's home area if the specified user name is
an empty string.</para>

<para><function>GetHomeByUID()</function> is similar to <function>GetHomeByName()</function> but
acquires the information based on the numeric UID of the user.</para>
Expand Down Expand Up @@ -387,10 +385,9 @@ node /org/freedesktop/home1 {
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. A home directory is locked automatically at system suspend only if all clients with open
references to the home directory specify that they support this functionality, and no client has
temporarily inhibited it (see <function>InhibitSuspendHome()</function> below); otherwise the directory
remains unlocked. This method is equivalent to <function>Acquire()</function> on the
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
Expand All @@ -412,25 +409,9 @@ node /org/freedesktop/home1 {
triggered deactivation is completed. This method is equivalent to <function>Release()</function> on the
<classname>org.freedesktop.home1.Home</classname> interface.</para>

<para><function>InhibitSuspendHome()</function> temporarily inhibits automatic locking during system
suspend for a home directory. It returns a file descriptor that inhibits this functionality for as long
as it is open. As mentioned above, locking a home directory requires a secure lock screen running
outside of the user context, and is likely to freeze any process that attempts to access the directory.
Thus, locking a home directory is a trade-off: it increases security, but prevents the client from
displaying any user content on its secure lock screen, including notifications, media controls, contact
information for incoming phone calls, and much more. A client may use this method to implement more
complicated automatic locking behavior for home directories, in order to solve some of these UX issues.
For instance, the client may choose to only lock the home directory and switch to the secure lock screen
if the device has been suspended for over 24 hours. Note that this inhibitor does not prevent clients from
calling <function>LockHome()</function>, and in fact clients will need to call <function>LockHome()</function>
manually as part of their custom behavior to lock the home directory. Clients should take care to ensure that
the file descriptor is closed in the event that their custom behavior fails or is disabled. This method is
equivalent to <function>InhibitSuspend()</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 locking during system suspend and have no clients inhibiting this behavior.
This is usually invoked automatically shortly before system suspend.</para>
that opted into automatic suspending during system suspend. This is usually invoked automatically
shortly before system suspend.</para>

<para><function>DeactivateAllHomes()</function> deactivates all home areas that are currently
active. This is usually invoked automatically shortly before system shutdown.</para>
Expand Down Expand Up @@ -492,7 +473,6 @@ node /org/freedesktop/home1/home {
out h send_fd);
@org.freedesktop.systemd1.Privileged("true")
Release();
InhibitSuspend(out h send_fd);
properties:
@org.freedesktop.DBus.Property.EmitsChangedSignal("const")
readonly s UserName = '...';
Expand Down Expand Up @@ -556,8 +536,6 @@ node /org/freedesktop/home1/home {

<variablelist class="dbus-method" generated="True" extra-ref="Release()"/>

<variablelist class="dbus-method" generated="True" extra-ref="InhibitSuspend()"/>

<variablelist class="dbus-property" generated="True" extra-ref="UserName"/>

<variablelist class="dbus-property" generated="True" extra-ref="UID"/>
Expand All @@ -579,14 +557,15 @@ node /org/freedesktop/home1/home {
<function>Update()</function>, <function>UpdateEx()</function>, <function>Resize()</function>,
<function>ChangePassword()</function>, <function>Lock()</function>, <function>Unlock()</function>,
<function>Acquire()</function>, <function>Ref()</function>, <function>RefUnrestricted()</function>,
<function>Release()</function>, <function>InhibitSuspend()</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>
<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. Clients can also easily operate
on their own home area by using the methods on the manager object with an empty string as the user name.
If the client has the home's object path already acquired in some way, however, it is preferable to operate
on the <classname>org.freedesktop.home1.Home</classname> objects instead.</para>
</refsect2>

<refsect2>
Expand All @@ -611,12 +590,12 @@ node /org/freedesktop/home1/home {
<title>History</title>
<refsect2>
<title>The Manager Object</title>
<para><function>InhibitSuspendHome()</function>, <function>ActivateHomeIfReferenced()</function>, <function>RefHomeUnrestricted()</function>,
<para><function>ActivateHomeIfReferenced()</function>, <function>RefHomeUnrestricted()</function>,
<function>CreateHomeEx()</function>, and <function>UpdateHomeEx()</function> were added in version 256.</para>
</refsect2>
<refsect2>
<title>Home Objects</title>
<para><function>InhibitSuspend()</function>, <function>ActivateIfReferenced()</function>, <function>RefUnrestricted()</function>, and
<para><function>ActivateIfReferenced()</function>, <function>RefUnrestricted()</function>, and
<function>UpdateEx()</function> were added in version 256.</para>
</refsect2>
</refsect1>
Expand Down
58 changes: 4 additions & 54 deletions src/home/homed-home-bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ int bus_home_method_authenticate(
return 1;
}

int bus_home_method_update_record(
int bus_home_update_record(
Home *h,
sd_bus_message *message,
UserRecord *hr,
Expand Down Expand Up @@ -487,7 +487,7 @@ int bus_home_method_update(
return r;
}

return bus_home_method_update_record(h, message, hr, blobs, flags, error);
return bus_home_update_record(h, message, hr, blobs, flags, error);
}

int bus_home_method_resize(
Expand Down Expand Up @@ -657,7 +657,7 @@ int bus_home_method_acquire(
return r;

/* This operation might not be something we can executed immediately, hence queue it */
fd = home_create_fifo(h, please_suspend ? HOME_FIFO_PLEASE_SUSPEND : HOME_FIFO_DONT_SUSPEND);
fd = home_create_fifo(h, please_suspend);
if (fd < 0)
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);

Expand Down Expand Up @@ -716,7 +716,7 @@ int bus_home_method_ref(
}
}

fd = home_create_fifo(h, please_suspend ? HOME_FIFO_PLEASE_SUSPEND : HOME_FIFO_DONT_SUSPEND);
fd = home_create_fifo(h, please_suspend);
if (fd < 0)
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);

Expand Down Expand Up @@ -745,51 +745,6 @@ int bus_home_method_release(
return 1;
}

int bus_home_method_inhibit_suspend(
sd_bus_message *message,
void *userdata,
sd_bus_error *error) {

_cleanup_close_ int fd = -EBADF;
Home *h = ASSERT_PTR(userdata);
HomeState state;
int r;

r = home_verify_polkit_async(
h,
message,
"org.freedesktop.home1.inhibit-suspend",
h->uid,
error);
if (r < 0)
return r;
if (r == 0)
return 1; /* Will call us back */

state = home_get_state(h);
switch (state) {
case HOME_ABSENT:
return sd_bus_error_setf(error, BUS_ERROR_HOME_ABSENT, "Home %s is currently missing or not plugged in.", h->user_name);
case HOME_UNFIXATED:
case HOME_INACTIVE:
case HOME_DIRTY:
return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_ACTIVE, "Home %s not active.", h->user_name);
case HOME_LOCKED:
return sd_bus_error_setf(error, BUS_ERROR_HOME_LOCKED, "Home %s is currently locked.", h->user_name);
default:
if (HOME_STATE_IS_ACTIVE(state))
break;

return sd_bus_error_setf(error, BUS_ERROR_HOME_BUSY, "An operation on home %s is currently being executed.", h->user_name);
}

fd = home_create_fifo(h, HOME_FIFO_INHIBIT_SUSPEND);
if (fd < 0)
return sd_bus_reply_method_errnof(message, fd, "Failed to allocate FIFO for %s: %m", h->user_name);

return sd_bus_reply_method_return(message, "h", fd);
}

/* We map a uid_t as uint32_t bus property, let's ensure this is safe. */
assert_cc(sizeof(uid_t) == sizeof(uint32_t));

Expand Down Expand Up @@ -949,11 +904,6 @@ const sd_bus_vtable home_vtable[] = {
bus_home_method_ref,
0),
SD_BUS_METHOD("Release", NULL, NULL, bus_home_method_release, 0),
SD_BUS_METHOD_WITH_ARGS("InhibitSuspend",
SD_BUS_NO_ARGS,
SD_BUS_RESULT("h", send_fd),
bus_home_method_inhibit_suspend,
SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END
};

Expand Down
4 changes: 2 additions & 2 deletions src/home/homed-home-bus.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,15 @@ int bus_home_method_remove(sd_bus_message *message, void *userdata, sd_bus_error
int bus_home_method_fixate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_authenticate(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_update(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_update_record(Home *home, sd_bus_message *message, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_error *error);
int bus_home_method_resize(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_change_password(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_lock(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_unlock(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_acquire(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_ref(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_release(sd_bus_message *message, void *userdata, sd_bus_error *error);
int bus_home_method_inhibit_suspend(sd_bus_message *message, void *userdata, sd_bus_error *error);

int bus_home_update_record(Home *home, sd_bus_message *message, UserRecord *hr, Hashmap *blobs, uint64_t flags, sd_bus_error *error);

extern const BusObjectImplementation home_object;

Expand Down
60 changes: 19 additions & 41 deletions src/home/homed-home.c
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,6 @@ Home *home_free(Home *h) {

h->ref_event_source_please_suspend = sd_event_source_disable_unref(h->ref_event_source_please_suspend);
h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);
h->inhibit_suspend_event_source = sd_event_source_disable_unref(h->inhibit_suspend_event_source);

h->pending_operations = ordered_set_free(h->pending_operations);
h->pending_event_source = sd_event_source_disable_unref(h->pending_event_source);
Expand Down Expand Up @@ -2707,9 +2706,6 @@ static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *u
if (h->ref_event_source_dont_suspend == s)
h->ref_event_source_dont_suspend = sd_event_source_disable_unref(h->ref_event_source_dont_suspend);

if (h->inhibit_suspend_event_source == s)
h->inhibit_suspend_event_source = sd_event_source_disable_unref(h->inhibit_suspend_event_source);

if (home_is_referenced(h))
return 0;

Expand All @@ -2725,42 +2721,25 @@ static int on_home_ref_eof(sd_event_source *s, int fd, uint32_t revents, void *u
return 0;
}

int home_create_fifo(Home *h, HomeFifoType type) {
static const struct {
const char *suffix;
const char *description;
size_t event_source;
} table[_HOME_FIFO_TYPE_MAX] = {
[HOME_FIFO_PLEASE_SUSPEND] = {
.suffix = ".please-suspend",
.description = "acquire-ref",
.event_source = offsetof(Home, ref_event_source_please_suspend),
},
[HOME_FIFO_DONT_SUSPEND] = {
.suffix = ".dont-suspend",
.description = "acquire-ref-dont-suspend",
.event_source = offsetof(Home, ref_event_source_dont_suspend),
},
[HOME_FIFO_INHIBIT_SUSPEND] = {
.suffix = ".inhibit-suspend",
.description = "inhibit-suspend",
.event_source = offsetof(Home, inhibit_suspend_event_source),
},
};

int home_create_fifo(Home *h, bool please_suspend) {
_cleanup_close_ int ret_fd = -EBADF;
sd_event_source **evt;
const char *fn;
sd_event_source **ss;
const char *fn, *suffix;
int r;

assert(h);
assert(type >= 0 && type < _HOME_FIFO_TYPE_MAX);

evt = (sd_event_source**) ((uint8_t*) h + table[type].event_source);
if (please_suspend) {
suffix = ".please-suspend";
ss = &h->ref_event_source_please_suspend;
} else {
suffix = ".dont-suspend";
ss = &h->ref_event_source_dont_suspend;
}

fn = strjoina("/run/systemd/home/", h->user_name, table[type].suffix);
fn = strjoina("/run/systemd/home/", h->user_name, suffix);

if (!*evt) {
if (!*ss) {
_cleanup_close_ int ref_fd = -EBADF;

(void) mkdir("/run/systemd/home/", 0755);
Expand All @@ -2771,19 +2750,20 @@ int home_create_fifo(Home *h, HomeFifoType type) {
if (ref_fd < 0)
return log_error_errno(errno, "Failed to open FIFO %s for reading: %m", fn);

r = sd_event_add_io(h->manager->event, evt, ref_fd, 0, on_home_ref_eof, h);
r = sd_event_add_io(h->manager->event, ss, ref_fd, 0, on_home_ref_eof, h);
if (r < 0)
return log_error_errno(r, "Failed to allocate reference FIFO event source: %m");

(void) sd_event_source_set_description(*evt, table[type].description);
(void) sd_event_source_set_description(*ss, "acquire-ref");

r = sd_event_source_set_priority(*evt, SD_EVENT_PRIORITY_IDLE-1);
r = sd_event_source_set_priority(*ss, SD_EVENT_PRIORITY_IDLE-1);
if (r < 0)
return r;

r = sd_event_source_set_io_fd_own(*evt, true);
r = sd_event_source_set_io_fd_own(*ss, true);
if (r < 0)
return log_error_errno(r, "Failed to pass ownership of FIFO event fd to event source: %m");

TAKE_FD(ref_fd);
}

Expand Down Expand Up @@ -2863,10 +2843,8 @@ bool home_is_referenced(Home *h) {
bool home_shall_suspend(Home *h) {
assert(h);

/* We lock the home area on suspend if... */
return h->ref_event_source_please_suspend && /* at least one client supports suspend, and... */
!h->ref_event_source_dont_suspend && /* no clients lack support for suspend, and... */
!h->inhibit_suspend_event_source; /* no client is temporarily inhibiting suspend */
/* Suspend if there's at least one client referencing this home directory that wants a suspend and none who does not. */
return h->ref_event_source_please_suspend && !h->ref_event_source_dont_suspend;
}

static int home_dispatch_release(Home *h, Operation *o) {
Expand Down
Loading

0 comments on commit 169b282

Please sign in to comment.