From 2cd2fb864a52e71a5f6c15aea1cc7e953674aeb6 Mon Sep 17 00:00:00 2001 From: Tomas Mraz Date: Tue, 7 Jun 2011 17:22:30 +0200 Subject: [PATCH] Detect the shared / mount and enable private mounts based on that. --- ChangeLog | 9 ++++ modules/pam_namespace/pam_namespace.8.xml | 7 +++- modules/pam_namespace/pam_namespace.c | 51 +++++++++++++++++++++++ 3 files changed, 65 insertions(+), 2 deletions(-) diff --git a/ChangeLog b/ChangeLog index 836804b3..bcd456c3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,12 @@ +2011-06-07 Tomas Mraz + + * modules/pam_namespace/pam_namespace.c (root_shared): New + function to detect shared / mount. + (pam_sm_open_session): Call the root_shared() and enable + private mounts based on that. + * modules/pam_namespace/pam_namespace.8.xml: Document the + automatic detection of shared / mount. + 2011-06-06 Tomas Mraz * modules/pam_group/pam_group.c (shift_bytes): Removed. diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml index f0ebe2c6..48021c80 100644 --- a/modules/pam_namespace/pam_namespace.8.xml +++ b/modules/pam_namespace/pam_namespace.8.xml @@ -243,11 +243,14 @@ - This option should be used on systems where the / mount point and + This option can be used on systems where the / mount point or its submounts are made shared (for example with a mount --make-rshared / command). The module will make the polyinstantiated directory mount points - private. + private. Normally the pam_namespace will try to detect the + shared / mount point and make the polyinstantiated directories + private automatically. This option has to be used just when + only a subtree is shared and / is not. diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c index d5a2d781..4a99184a 100644 --- a/modules/pam_namespace/pam_namespace.c +++ b/modules/pam_namespace/pam_namespace.c @@ -1890,6 +1890,53 @@ static int ctxt_based_inst_needed(void) } #endif +static int root_shared(void) +{ + FILE *f; + char *line = NULL; + size_t n = 0; + int rv = 0; + + f = fopen("/proc/self/mountinfo", "r"); + + if (f == NULL) + return 0; + + while(getline(&line, &n, f) != -1) { + char *l; + char *sptr; + int i; + + l = line; + sptr = NULL; + for (i = 0; i < 7; i++) { + char *tok; + + tok = strtok_r(l, " ", &sptr); + l = NULL; + if (tok == NULL) + /* next mountinfo line */ + break; + + if (i == 4 && strcmp(tok, "/") != 0) + /* next mountinfo line */ + break; + + if (i == 6) { + if (strncmp(tok, "shared:", 7) == 0) + /* there might be more / mounts, the last one counts */ + rv = 1; + else + rv = 0; + } + } + } + + free(line); + fclose(f); + + return rv; +} static int get_user_data(struct instance_data *idata) { @@ -2002,6 +2049,10 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, if (retval != PAM_SUCCESS) return retval; + if (root_shared()) { + idata.flags |= PAMNS_MOUNT_PRIVATE; + } + /* * Parse namespace configuration file which lists directories to * polyinstantiate, directory where instance directories are to -- 2.40.0