homework: allow specifying a dir component in CIFS services

Allow specifying CIFS services in the format //host/service/subdir/… to
allow multiple homedirs on the same share, and not in the main dir of
the share.

All other backends allow placing the data store at arbitrary places,
let's allow this too for the CIFS backend. This is particularly useful
for testing.
This commit is contained in:
Lennart Poettering
2021-10-27 22:37:56 +02:00
parent 2b9855f9d2
commit bf15879b39
5 changed files with 43 additions and 7 deletions
+28 -4
View File
@@ -7,6 +7,7 @@
#include "fs-util.h"
#include "homework-cifs.h"
#include "homework-mount.h"
#include "mkdir.h"
#include "mount-util.h"
#include "process-util.h"
#include "stat-util.h"
@@ -18,6 +19,7 @@ int home_setup_cifs(
HomeSetupFlags flags,
HomeSetup *setup) {
_cleanup_free_ char *chost = NULL, *cservice = NULL, *cdir = NULL, *chost_and_service = NULL, *j = NULL;
char **pw;
int r;
@@ -38,6 +40,15 @@ int home_setup_cifs(
if (!h->cifs_service)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "User record lacks CIFS service, refusing.");
r = parse_cifs_service(h->cifs_service, &chost, &cservice, &cdir);
if (r < 0)
return log_error_errno(r, "Failed parse CIFS service specification: %m");
/* Just the host and service part, without the directory */
chost_and_service = strjoin("//", chost, "/", cservice);
if (!chost_and_service)
return log_oom();
r = home_unshare_and_mkdir();
if (r < 0)
return r;
@@ -78,7 +89,7 @@ int home_setup_cifs(
if (r == 0) {
/* Child */
execl("/bin/mount", "/bin/mount", "-n", "-t", "cifs",
h->cifs_service, HOME_RUNTIME_WORK_DIR,
chost_and_service, HOME_RUNTIME_WORK_DIR,
"-o", options, NULL);
log_error_errno(errno, "Failed to execute mount: %m");
@@ -104,10 +115,23 @@ int home_setup_cifs(
if (r < 0)
return r;
setup->root_fd = open(HOME_RUNTIME_WORK_DIR, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (cdir) {
j = path_join(HOME_RUNTIME_WORK_DIR, cdir);
if (!j)
return log_oom();
if (FLAGS_SET(flags, HOME_SETUP_CIFS_MKDIR)) {
r = mkdir_p(j, 0700);
if (r < 0)
return log_error_errno(r, "Failed to create CIFS subdirectory: %m");
}
}
setup->root_fd = open(j ?: HOME_RUNTIME_WORK_DIR, O_RDONLY|O_CLOEXEC|O_DIRECTORY|O_NOFOLLOW);
if (setup->root_fd < 0)
return log_error_errno(errno, "Failed to open home directory: %m");
setup->mount_suffix = TAKE_PTR(cdir);
return 0;
}
@@ -139,7 +163,7 @@ int home_activate_cifs(
setup->root_fd = safe_close(setup->root_fd);
r = home_move_mount(NULL, hd);
r = home_move_mount(setup->mount_suffix, hd);
if (r < 0)
return r;
@@ -171,7 +195,7 @@ int home_create_cifs(UserRecord *h, HomeSetup *setup, UserRecord **ret_home) {
return log_error_errno(errno, "Unable to detect whether /sbin/mount.cifs exists: %m");
}
r = home_setup_cifs(h, 0, setup);
r = home_setup_cifs(h, HOME_SETUP_CIFS_MKDIR, setup);
if (r < 0)
return r;
+2
View File
@@ -365,6 +365,8 @@ int home_setup_done(HomeSetup *setup) {
if (setup->do_drop_caches)
drop_caches_now();
setup->mount_suffix = mfree(setup->mount_suffix);
return r;
}
+5
View File
@@ -37,6 +37,8 @@ typedef struct HomeSetup {
uint64_t partition_offset;
uint64_t partition_size;
char *mount_suffix; /* The directory to use as home dir is this path below /run/systemd/user-home-mount */
} HomeSetup;
typedef struct PasswordCache {
@@ -66,6 +68,9 @@ static inline bool password_cache_contains(const PasswordCache *cache, const cha
/* Various flags for the operation of setting up a home directory */
typedef enum HomeSetupFlags {
HOME_SETUP_ALREADY_ACTIVATED = 1 << 0, /* Open an already activated home, rather than activate it afresh */
/* CIFS backend: */
HOME_SETUP_CIFS_MKDIR = 1 << 1, /* Create CIFS subdir when missing */
} HomeSetupFlags;
int home_setup_done(HomeSetup *setup);