]> git.proxmox.com Git - mirror_zfs.git/commitdiff
PAM: add 'forceunmount' flag
authorVal Packett <val@packett.cool>
Sat, 6 May 2023 01:02:13 +0000 (22:02 -0300)
committerBrian Behlendorf <behlendorf1@llnl.gov>
Thu, 1 Jun 2023 00:01:02 +0000 (17:01 -0700)
Probably not always a good idea, but it's nice to have the option.
It is a workaround for FreeBSD calling the PAM session end earier than
the last process is actually done touching the mount, for example.

Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov>
Reviewed-by: Felix Dörre <felix@dogcraft.de>
Signed-off-by: Val Packett <val@packett.cool>
Closes #14834

contrib/pam_zfs_key/pam_zfs_key.c

index 259ac7a8f1919174f9a1f67711ef0ee5e8f12090..c6abb34619d60bd63c58c959b4cb4875eb4c379c 100644 (file)
@@ -406,14 +406,14 @@ out:
 }
 
 static int
-unmount_unload(pam_handle_t *pamh, const char *ds_name)
+unmount_unload(pam_handle_t *pamh, const char *ds_name, boolean_t force)
 {
        zfs_handle_t *ds = zfs_open(g_zfs, ds_name, ZFS_TYPE_FILESYSTEM);
        if (ds == NULL) {
                pam_syslog(pamh, LOG_ERR, "dataset %s not found", ds_name);
                return (-1);
        }
-       int ret = zfs_unmount(ds, NULL, 0);
+       int ret = zfs_unmount(ds, NULL, force ? MS_FORCE : 0);
        if (ret) {
                pam_syslog(pamh, LOG_ERR, "zfs_unmount failed with: %d", ret);
                zfs_close(ds);
@@ -438,6 +438,7 @@ typedef struct {
        uid_t uid;
        const char *username;
        boolean_t unmount_and_unload;
+       boolean_t force_unmount;
        boolean_t recursive_homes;
 } zfs_key_config_t;
 
@@ -473,6 +474,7 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
        config->uid = entry->pw_uid;
        config->username = name;
        config->unmount_and_unload = B_TRUE;
+       config->force_unmount = B_FALSE;
        config->recursive_homes = B_FALSE;
        config->dsname = NULL;
        config->homedir = NULL;
@@ -485,6 +487,8 @@ zfs_key_config_load(pam_handle_t *pamh, zfs_key_config_t *config,
                        config->runstatedir = strdup(argv[c] + 12);
                } else if (strcmp(argv[c], "nounmount") == 0) {
                        config->unmount_and_unload = B_FALSE;
+               } else if (strcmp(argv[c], "forceunmount") == 0) {
+                       config->force_unmount = B_TRUE;
                } else if (strcmp(argv[c], "recursive_homes") == 0) {
                        config->recursive_homes = B_TRUE;
                } else if (strcmp(argv[c], "prop_mountpoint") == 0) {
@@ -882,7 +886,7 @@ pam_sm_close_session(pam_handle_t *pamh, int flags,
                        zfs_key_config_free(&config);
                        return (PAM_SESSION_ERR);
                }
-               if (unmount_unload(pamh, dataset) == -1) {
+               if (unmount_unload(pamh, dataset, config.force_unmount) == -1) {
                        free(dataset);
                        pam_zfs_free();
                        zfs_key_config_free(&config);