diff --git a/src/home/homed-home-bus.c b/src/home/homed-home-bus.c index 5977ff2a47..b459cadcbf 100644 --- a/src/home/homed-home-bus.c +++ b/src/home/homed-home-bus.c @@ -144,15 +144,31 @@ int bus_home_method_activate( _cleanup_(user_record_unrefp) UserRecord *secret = NULL; Home *h = ASSERT_PTR(userdata); + bool if_referenced; int r; assert(message); + if_referenced = endswith(sd_bus_message_get_member(message), "IfReferenced"); + + r = bus_verify_polkit_async_full( + message, + "org.freedesktop.home1.activate-home", + /* details= */ NULL, + /* interctive= */ false, + h->uid, + &h->manager->polkit_registry, + error); + if (r < 0) + return r; + if (r == 0) + return 1; /* Will call us back */ + r = bus_message_read_secret(message, &secret, error); if (r < 0) return r; - r = home_activate(h, secret, error); + r = home_activate(h, if_referenced, secret, error); if (r < 0) return r; @@ -822,7 +838,12 @@ const sd_bus_vtable home_vtable[] = { SD_BUS_ARGS("s", secret), SD_BUS_NO_RESULT, bus_home_method_activate, - SD_BUS_VTABLE_SENSITIVE), + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_ARGS("ActivateIfReferenced", + SD_BUS_ARGS("s", secret), + SD_BUS_NO_RESULT, + bus_home_method_activate, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_METHOD("Deactivate", NULL, NULL, bus_home_method_deactivate, 0), SD_BUS_METHOD("Unregister", NULL, NULL, bus_home_method_unregister, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD_WITH_ARGS("Realize", diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 8b0df9175e..2134f4352f 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -1383,12 +1383,15 @@ static int home_activate_internal(Home *h, UserRecord *secret, HomeState for_sta return 0; } -int home_activate(Home *h, UserRecord *secret, sd_bus_error *error) { +int home_activate(Home *h, bool if_referenced, UserRecord *secret, sd_bus_error *error) { int r; assert(h); assert(secret); + if (if_referenced && !home_is_referenced(h)) + return sd_bus_error_setf(error, BUS_ERROR_HOME_NOT_REFERENCED, "Home %s is currently not referenced.", h->user_name); + switch (home_get_state(h)) { case HOME_UNFIXATED: return home_fixate_internal(h, secret, HOME_FIXATING_FOR_ACTIVATION, error); diff --git a/src/home/homed-home.h b/src/home/homed-home.h index b8b0046422..6c069ab5f0 100644 --- a/src/home/homed-home.h +++ b/src/home/homed-home.h @@ -190,7 +190,7 @@ int home_save_record(Home *h); int home_unlink_record(Home *h); int home_fixate(Home *h, UserRecord *secret, sd_bus_error *error); -int home_activate(Home *h, UserRecord *secret, sd_bus_error *error); +int home_activate(Home *h, bool if_referenced, UserRecord *secret, sd_bus_error *error); int home_authenticate(Home *h, UserRecord *secret, sd_bus_error *error); int home_deactivate(Home *h, bool force, sd_bus_error *error); int home_create(Home *h, UserRecord *secret, sd_bus_error *error); diff --git a/src/home/homed-manager-bus.c b/src/home/homed-manager-bus.c index c484ef7ac2..c8e232f425 100644 --- a/src/home/homed-manager-bus.c +++ b/src/home/homed-manager-bus.c @@ -737,7 +737,12 @@ static const sd_bus_vtable manager_vtable[] = { SD_BUS_ARGS("s", user_name, "s", secret), SD_BUS_NO_RESULT, method_activate_home, - SD_BUS_VTABLE_SENSITIVE), + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), + SD_BUS_METHOD_WITH_ARGS("ActivateHomeIfReferenced", + SD_BUS_ARGS("s", user_name, "s", secret), + SD_BUS_NO_RESULT, + method_activate_home, + SD_BUS_VTABLE_UNPRIVILEGED|SD_BUS_VTABLE_SENSITIVE), SD_BUS_METHOD_WITH_ARGS("DeactivateHome", SD_BUS_ARGS("s", user_name), SD_BUS_NO_RESULT, diff --git a/src/home/org.freedesktop.home1.conf b/src/home/org.freedesktop.home1.conf index b0c18f261e..d2c4b9dd29 100644 --- a/src/home/org.freedesktop.home1.conf +++ b/src/home/org.freedesktop.home1.conf @@ -57,6 +57,10 @@ send_interface="org.freedesktop.home1.Manager" send_member="ActivateHome"/> + + @@ -147,6 +151,10 @@ send_interface="org.freedesktop.home1.Home" send_member="Activate"/> + + diff --git a/src/home/org.freedesktop.home1.policy b/src/home/org.freedesktop.home1.policy index 2ac710d66c..be32b2e8e4 100644 --- a/src/home/org.freedesktop.home1.policy +++ b/src/home/org.freedesktop.home1.policy @@ -78,4 +78,14 @@ auth_admin_keep + + + Activate a home area + Authentication is required to activate a user's home area. + + auth_admin_keep + auth_admin_keep + auth_admin_keep + + diff --git a/src/libsystemd/sd-bus/bus-common-errors.c b/src/libsystemd/sd-bus/bus-common-errors.c index efdd6539cc..e44795b1d3 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.c +++ b/src/libsystemd/sd-bus/bus-common-errors.c @@ -147,6 +147,7 @@ BUS_ERROR_MAP_ELF_REGISTER const sd_bus_error_map bus_common_errors[] = { SD_BUS_ERROR_MAP(BUS_ERROR_HOME_CANT_AUTHENTICATE, EKEYREVOKED), SD_BUS_ERROR_MAP(BUS_ERROR_HOME_IN_USE, EADDRINUSE), SD_BUS_ERROR_MAP(BUS_ERROR_REBALANCE_NOT_NEEDED, EALREADY), + SD_BUS_ERROR_MAP(BUS_ERROR_HOME_NOT_REFERENCED, EBADR), SD_BUS_ERROR_MAP_END }; diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index 2961ee4a9e..36f53dbde1 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -152,5 +152,6 @@ #define BUS_ERROR_HOME_CANT_AUTHENTICATE "org.freedesktop.home1.HomeCantAuthenticate" #define BUS_ERROR_HOME_IN_USE "org.freedesktop.home1.HomeInUse" #define BUS_ERROR_REBALANCE_NOT_NEEDED "org.freedesktop.home1.RebalanceNotNeeded" +#define BUS_ERROR_HOME_NOT_REFERENCED "org.freedesktop.home1.HomeNotReferenced" BUS_ERROR_MAP_ELF_USE(bus_common_errors);