]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homed: add a ActivateHomeIfReferenced() bus call
authorLennart Poettering <lennart@poettering.net>
Mon, 27 Nov 2023 16:05:54 +0000 (17:05 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 14 Feb 2024 14:04:15 +0000 (15:04 +0100)
This is very similar to ActivateHome() but will fail if the home
directory is not referenced yet. Or in other words, this doesn't add any
new reference, but simply is the other side of RefUnrestricted(): if we
allowed a home dir to be referenced without it actually being active,
then this can catch up with things and activated what was previously
referenced already.

This also relaxes access rights to that users can always activate their
own home dirs. This is useful once we allow user code to run without the
home dir being activated.

src/home/homed-home-bus.c
src/home/homed-home.c
src/home/homed-home.h
src/home/homed-manager-bus.c
src/home/org.freedesktop.home1.conf
src/home/org.freedesktop.home1.policy
src/libsystemd/sd-bus/bus-common-errors.c
src/libsystemd/sd-bus/bus-common-errors.h

index 5977ff2a47e1b5aa805c36ec92133612f3d4c6e7..b459cadcbfc2b795bd8ac1cc88ffef15e04b4912 100644 (file)
@@ -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",
index 8b0df9175ef2b5f7a4cea9e8eba09195a44977e1..2134f4352f18abe16aef144b36877b8a2150bcda 100644 (file)
@@ -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);
index b8b004642294628db7bd2c68ebcfe32a280ca79c..6c069ab5f0269d48c9186a2d97a81af0a2151a61 100644 (file)
@@ -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);
index c484ef7ac26d217d03b51f29c5de95b63f3c2b2e..c8e232f4257c91846c0e92b8e028f4cd5f72e463 100644 (file)
@@ -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,
index b0c18f261e4844fe5dde463511dbef8e85b2e90d..d2c4b9dd290d12af9311eecb5c9e685df0c8807a 100644 (file)
                        send_interface="org.freedesktop.home1.Manager"
                        send_member="ActivateHome"/>
 
+                <allow send_destination="org.freedesktop.home1"
+                       send_interface="org.freedesktop.home1.Manager"
+                       send_member="ActivateHomeIfReferenced"/>
+
                 <allow send_destination="org.freedesktop.home1"
                        send_interface="org.freedesktop.home1.Manager"
                        send_member="DeactivateHome"/>
                        send_interface="org.freedesktop.home1.Home"
                        send_member="Activate"/>
 
+                <allow send_destination="org.freedesktop.home1"
+                       send_interface="org.freedesktop.home1.Home"
+                       send_member="ActivateIfReferenced"/>
+
                 <allow send_destination="org.freedesktop.home1"
                        send_interface="org.freedesktop.home1.Home"
                        send_member="Deactivate"/>
index 2ac710d66c6101ab0a11b24134a1ee75079e3ed5..be32b2e8e4e198dd7256f110d0c7a4b420f9bf73 100644 (file)
                         <allow_active>auth_admin_keep</allow_active>
                 </defaults>
         </action>
+
+        <action id="org.freedesktop.home1.activate-home">
+                <description gettext-domain="systemd">Activate a home area</description>
+                <message gettext-domain="systemd">Authentication is required to activate a user's home area.</message>
+                <defaults>
+                        <allow_any>auth_admin_keep</allow_any>
+                        <allow_inactive>auth_admin_keep</allow_inactive>
+                        <allow_active>auth_admin_keep</allow_active>
+                </defaults>
+        </action>
 </policyconfig>
index efdd6539ccebd017523f92d2b18878870ab64112..e44795b1d3033f1ca035f17ba8ceb2197ad77ca8 100644 (file)
@@ -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
 };
index 2961ee4a9ecaba87902803cdba114752e8585045..36f53dbde14b75dac7652eb443d67e614a83b019 100644 (file)
 #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);