summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog9
-rw-r--r--modules/pam_namespace/pam_namespace.8.xml7
-rw-r--r--modules/pam_namespace/pam_namespace.c51
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 <tm@t8m.info>
+
+ * 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 <tm@t8m.info>
* 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 @@
</term>
<listitem>
<para>
- 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
<command>mount --make-rshared /</command> 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.
</para>
</listitem>
</varlistentry>
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