homed: make clean that --storage=directory --image-path=/dev/some-block-device is...
authorLennart Poettering <lennart@poettering.net>
Fri, 18 Sep 2020 17:37:05 +0000 (19:37 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 20 Sep 2020 10:09:59 +0000 (12:09 +0200)
The directory backend needs a file system path, and not a raw block
device. That's only supported for the LUKS2 backend.

Let's make this clearer in the man page and also generate a better error
message if attempted anyway.

Fixes: #17068
(cherry picked from commit f9d525ae558105bf7fd77ad76e4fdb135bb9f634)

man/homectl.xml
src/home/homed-home.c

index 0724749c07a43857d71b6cf26c1da908c3ab8f32..78b36062effc386062488c380d3dd3b4e04dfd15 100644 (file)
 
         <listitem><para>Takes a file system path. Configures where to place the user's home directory. When
         LUKS2 storage is used refers to the path to the loopback file, otherwise to the path to the home
-        directory. When unspecified defaults to <filename>/home/$USER.home</filename> when LUKS storage is
-        used and <filename>/home/$USER.homedir</filename> for the other storage mechanisms. Not defined for
-        the <literal>cifs</literal> storage mechanism. To use LUKS2 storage on a regular block device (for
-        example a USB stick) pass the path to the block device here.</para></listitem>
+        directory (which may be in <filename>/home/</filename> or any other accessible filesystem). When
+        unspecified defaults to <filename>/home/$USER.home</filename> when LUKS storage is used and
+        <filename>/home/$USER.homedir</filename> for the other storage mechanisms. Not defined for the
+        <literal>cifs</literal> storage mechanism. To use LUKS2 storage on a regular block device (for
+        example a USB stick) pass the path to the block device here. Specifying the path to a directory here
+        when using LUKS2 storage is not allowed. Similar, specifying the path to a regular file or device
+        node is not allowed if any of the other storage backends are used.</para></listitem>
       </varlistentry>
 
       <varlistentry>
index b124a3e5d908b456149ed57e46280e7cb573fa2f..3cdd1ef0e94e78c7a41cd12a026f91051443248c 100644 (file)
@@ -1267,15 +1267,22 @@ int home_create(Home *h, UserRecord *secret, sd_bus_error *error) {
         assert(h);
 
         switch (home_get_state(h)) {
-        case HOME_INACTIVE:
+        case HOME_INACTIVE: {
+                int t;
+
                 if (h->record->storage < 0)
                         break; /* if no storage is defined we don't know what precisely to look for, hence
                                 * HOME_INACTIVE is OK in that case too. */
 
-                if (IN_SET(user_record_test_image_path(h->record), USER_TEST_MAYBE, USER_TEST_UNDEFINED))
+                t = user_record_test_image_path(h->record);
+                if (IN_SET(t, USER_TEST_MAYBE, USER_TEST_UNDEFINED))
                         break; /* And if the image path test isn't conclusive, let's also go on */
 
-                _fallthrough_;
+                if (IN_SET(t, -EBADFD, -ENOTDIR))
+                        return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists or has wrong inode type.", h->user_name);
+
+                return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Selected home image of user %s already exists.", h->user_name);
+        }
         case HOME_UNFIXATED:
                 return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name);
         case HOME_ABSENT: