homed: make clean that --storage=directory --image-path=/dev/some-block-device is not supported

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
This commit is contained in:
Lennart Poettering 2020-09-18 19:37:05 +02:00
parent 9796a9fbad
commit f9d525ae55
2 changed files with 17 additions and 7 deletions

View File

@ -566,10 +566,13 @@
<listitem><para>Takes a file system path. Configures where to place the user's home directory. When <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 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 directory (which may be in <filename>/home/</filename> or any other accessible filesystem). When
used and <filename>/home/$USER.homedir</filename> for the other storage mechanisms. Not defined for unspecified defaults to <filename>/home/$USER.home</filename> when LUKS storage is used and
the <literal>cifs</literal> storage mechanism. To use LUKS2 storage on a regular block device (for <filename>/home/$USER.homedir</filename> for the other storage mechanisms. Not defined for the
example a USB stick) pass the path to the block device here.</para></listitem> <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>
<varlistentry> <varlistentry>

View File

@ -1280,15 +1280,22 @@ int home_create(Home *h, UserRecord *secret, sd_bus_error *error) {
assert(h); assert(h);
switch (home_get_state(h)) { switch (home_get_state(h)) {
case HOME_INACTIVE: case HOME_INACTIVE: {
int t;
if (h->record->storage < 0) if (h->record->storage < 0)
break; /* if no storage is defined we don't know what precisely to look for, hence break; /* if no storage is defined we don't know what precisely to look for, hence
* HOME_INACTIVE is OK in that case too. */ * 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 */ 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: case HOME_UNFIXATED:
case HOME_DIRTY: case HOME_DIRTY:
return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name); return sd_bus_error_setf(error, BUS_ERROR_HOME_EXISTS, "Home of user %s already exists.", h->user_name);