diff --git a/man/org.freedesktop.home1.xml b/man/org.freedesktop.home1.xml index 8ac3d96086c29..6fe3bb3ce0821 100644 --- a/man/org.freedesktop.home1.xml +++ b/man/org.freedesktop.home1.xml @@ -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") @@ -187,8 +185,6 @@ node /org/freedesktop/home1 { - - @@ -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 - org.freedesktop.home1.Home interface documented below. + org.freedesktop.home1.Home 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. GetHomeByUID() is similar to GetHomeByName() but acquires the information based on the numeric UID of the user. @@ -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 InhibitSuspendHome() below); otherwise the directory - remains unlocked. This method is equivalent to Acquire() 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 Acquire() on the org.freedesktop.home1.Home interface. RefHome() is similar to AcquireHome() but takes no user @@ -412,25 +409,9 @@ node /org/freedesktop/home1 { triggered deactivation is completed. This method is equivalent to Release() on the org.freedesktop.home1.Home interface. - InhibitSuspendHome() 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 LockHome(), and in fact clients will need to call LockHome() - 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 InhibitSuspend() on the org.freedesktop.home1.Home - interface. - LockAllHomes() 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. + that opted into automatic suspending during system suspend. This is usually invoked automatically + shortly before system suspend. DeactivateAllHomes() deactivates all home areas that are currently active. This is usually invoked automatically shortly before system shutdown. @@ -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 = '...'; @@ -556,8 +536,6 @@ node /org/freedesktop/home1/home { - - @@ -579,14 +557,15 @@ node /org/freedesktop/home1/home { Update(), UpdateEx(), Resize(), ChangePassword(), Lock(), Unlock(), Acquire(), Ref(), RefUnrestricted(), - Release(), InhibitSuspend() operate like their matching counterparts - on the org.freedesktop.home1.Manager 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 org.freedesktop.home1.Home objects - instead. + Release(), + operate like their matching counterparts on the org.freedesktop.home1.Manager + 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 org.freedesktop.home1.Home objects instead. @@ -611,12 +590,12 @@ node /org/freedesktop/home1/home { History The Manager Object - InhibitSuspendHome(), ActivateHomeIfReferenced(), RefHomeUnrestricted(), + ActivateHomeIfReferenced(), RefHomeUnrestricted(), CreateHomeEx(), and UpdateHomeEx() were added in version 256. Home Objects - InhibitSuspend(), ActivateIfReferenced(), RefUnrestricted(), and + ActivateIfReferenced(), RefUnrestricted(), and UpdateEx() were added in version 256. diff --git a/src/home/homed-home-bus.c b/src/home/homed-home-bus.c index 368ce2d9e23d6..624cbdb3d33d9 100644 --- a/src/home/homed-home-bus.c +++ b/src/home/homed-home-bus.c @@ -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, @@ -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( @@ -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); @@ -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); @@ -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)); @@ -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 }; diff --git a/src/home/homed-home-bus.h b/src/home/homed-home-bus.h index 9ba2cf1252504..1644bc8066a42 100644 --- a/src/home/homed-home-bus.h +++ b/src/home/homed-home-bus.h @@ -17,7 +17,6 @@ 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); @@ -25,7 +24,8 @@ int bus_home_method_unlock(sd_bus_message *message, void *userdata, sd_bus_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; diff --git a/src/home/homed-home.c b/src/home/homed-home.c index edde6fafd3cbb..e0c8637c4c754 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -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); @@ -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; @@ -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); @@ -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); } @@ -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) { diff --git a/src/home/homed-home.h b/src/home/homed-home.h index 0f3d1ce3251b4..7f42461a45df6 100644 --- a/src/home/homed-home.h +++ b/src/home/homed-home.h @@ -139,17 +139,12 @@ struct Home { bool unregister_on_failure; /* The reading side of a FIFO stored in /run/systemd/home/, the writing side being used for reference - * counting. The references dropped to zero as soon as we see EOF. This concept exists thrice: once - * for clients that are fine if we lock the home directory on system suspend, once for clients - * that are not ok with that, and once for clients that are usually ok with it but temporarily - * want to opt-out so that they can implement more advanced behavior on their own. This allows - * us to determine for each home whether there are any clients that don't support suspend at this - * moment. */ + * counting. The references dropped to zero as soon as we see EOF. This concept exists twice: once + * for clients that are fine if we suspend the home directory on system suspend, and once for clients + * that are not ok with that. This allows us to determine for each home whether there are any clients + * that support unsuspend. */ sd_event_source *ref_event_source_please_suspend; sd_event_source *ref_event_source_dont_suspend; - /* This is distinct from ref_event_source_dont_suspend because it can be obtained from unprivileged - * code, and thus we don't count it as a reference on the home area. */ - sd_event_source *inhibit_suspend_event_source; /* Any pending operations we still need to execute. These are for operations we want to queue if we * can't execute them right-away. */ @@ -215,15 +210,7 @@ int home_killall(Home *h); int home_augment_status(Home *h, UserRecordLoadFlags flags, UserRecord **ret); -typedef enum { - HOME_FIFO_PLEASE_SUSPEND, - HOME_FIFO_DONT_SUSPEND, - HOME_FIFO_INHIBIT_SUSPEND, - _HOME_FIFO_TYPE_MAX, - _HOME_FIFO_TYPE_INVALID = -EINVAL, -} HomeFifoType; -int home_create_fifo(Home *h, HomeFifoType mode); - +int home_create_fifo(Home *h, bool please_suspend); int home_schedule_operation(Home *h, Operation *o, sd_bus_error *error); int home_auto_login(Home *h, char ***ret_seats); diff --git a/src/home/homed-manager-bus.c b/src/home/homed-manager-bus.c index 1e63012a06f4a..403a7d0213b40 100644 --- a/src/home/homed-manager-bus.c +++ b/src/home/homed-manager-bus.c @@ -592,7 +592,7 @@ static int method_update_home(sd_bus_message *message, void *userdata, sd_bus_er if (!h) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_HOME, "No home for user %s known", hr->user_name); - return bus_home_method_update_record(h, message, hr, blobs, flags, error); + return bus_home_update_record(h, message, hr, blobs, flags, error); } static int method_resize_home(sd_bus_message *message, void *userdata, sd_bus_error *error) { @@ -623,10 +623,6 @@ static int method_release_home(sd_bus_message *message, void *userdata, sd_bus_e return generic_home_method(userdata, message, bus_home_method_release, error); } -static int method_inhibit_suspend_home(sd_bus_message *message, void *userdata, sd_bus_error *error) { - return generic_home_method(userdata, message, bus_home_method_inhibit_suspend, error); -} - static int method_lock_all_homes(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_(operation_unrefp) Operation *o = NULL; bool waiting = false; @@ -901,12 +897,6 @@ static const sd_bus_vtable manager_vtable[] = { method_release_home, 0), - SD_BUS_METHOD_WITH_ARGS("InhibitSuspendHome", - SD_BUS_ARGS("s", user_name), - SD_BUS_RESULT("h", send_fd), - method_inhibit_suspend_home, - SD_BUS_VTABLE_UNPRIVILEGED), - /* An operation that acts on all homes that allow it */ SD_BUS_METHOD("LockAllHomes", NULL, NULL, method_lock_all_homes, 0), SD_BUS_METHOD("DeactivateAllHomes", NULL, NULL, method_deactivate_all_homes, 0), diff --git a/src/home/org.freedesktop.home1.conf b/src/home/org.freedesktop.home1.conf index 9ac34aea55f67..b8085929b0108 100644 --- a/src/home/org.freedesktop.home1.conf +++ b/src/home/org.freedesktop.home1.conf @@ -137,10 +137,6 @@ send_interface="org.freedesktop.home1.Manager" send_member="ReleaseHome"/> - - @@ -227,10 +223,6 @@ send_interface="org.freedesktop.home1.Home" send_member="Release"/> - - diff --git a/src/home/org.freedesktop.home1.policy b/src/home/org.freedesktop.home1.policy index be32b2e8e4e19..3b19ed3ed5fc0 100644 --- a/src/home/org.freedesktop.home1.policy +++ b/src/home/org.freedesktop.home1.policy @@ -69,16 +69,6 @@ - - Inhibit automatic lock of a home area - Authentication is required to inhibit automatic lock of a user's home area. - - auth_admin_keep - auth_admin_keep - auth_admin_keep - - - Activate a home area Authentication is required to activate a user's home area.