]> granicus.if.org Git - linux-pam/commitdiff
Detect the shared / mount and enable private mounts based on that.
authorTomas Mraz <tmraz@fedoraproject.org>
Tue, 7 Jun 2011 15:22:30 +0000 (17:22 +0200)
committerTomas Mraz <tmraz@fedoraproject.org>
Tue, 7 Jun 2011 15:22:30 +0000 (17:22 +0200)
ChangeLog
modules/pam_namespace/pam_namespace.8.xml
modules/pam_namespace/pam_namespace.c

index 836804b31baed4b1802130e63622dc480b3b2f78..bcd456c3eb406e29b55fd6745d1b095d0cd7b083 100644 (file)
--- 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.
index f0ebe2c6fd63e0ccd88d840b14e20c86bfe979b9..48021c80e186fc00ae1b943ac1042fb60e69d93b 100644 (file)
         </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>
index d5a2d781c2e50f4c08501fa54d7af8b8e05ec038..4a99184acaa376390202e1b009b60e5da175a03a 100644 (file)
@@ -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