115 lines
4.8 KiB
Diff
115 lines
4.8 KiB
Diff
diff -up Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.8.xml.rslave Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.8.xml
|
|
--- Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.8.xml.rslave 2011-06-21 11:04:56.000000000 +0200
|
|
+++ Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.8.xml 2012-01-31 16:40:36.495716240 +0100
|
|
@@ -246,12 +246,18 @@
|
|
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. Normally the pam_namespace will try to detect the
|
|
+ The module will mark the whole directory tree so any mount and
|
|
+ unmount operations in the polyinstantiation namespace are 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>
|
|
+ <para>
|
|
+ Note that mounts and unmounts done in the private namespace will not
|
|
+ affect the parent namespace if this option is used or when the
|
|
+ shared / mount point is autodetected.
|
|
+ </para>
|
|
</listitem>
|
|
</varlistentry>
|
|
|
|
diff -up Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.c.rslave Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.c
|
|
--- Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.c.rslave 2011-06-21 11:04:56.000000000 +0200
|
|
+++ Linux-PAM-1.1.5/modules/pam_namespace/pam_namespace.c 2012-01-31 16:42:07.762506791 +0100
|
|
@@ -1003,7 +1003,7 @@ static int protect_mount(int dfd, const
|
|
return 0;
|
|
}
|
|
|
|
-static int protect_dir(const char *path, mode_t mode, int do_mkdir, int always,
|
|
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
|
|
struct instance_data *idata)
|
|
{
|
|
char *p = strdup(path);
|
|
@@ -1082,7 +1082,7 @@ static int protect_dir(const char *path,
|
|
}
|
|
}
|
|
|
|
- if ((flags & O_NOFOLLOW) || always) {
|
|
+ if (flags & O_NOFOLLOW) {
|
|
/* we are inside user-owned dir - protect */
|
|
if (protect_mount(rv, p, idata) == -1) {
|
|
save_errno = errno;
|
|
@@ -1124,7 +1124,7 @@ static int check_inst_parent(char *ipath
|
|
if (trailing_slash)
|
|
*trailing_slash = '\0';
|
|
|
|
- dfd = protect_dir(inst_parent, 0, 1, 0, idata);
|
|
+ dfd = protect_dir(inst_parent, 0, 1, idata);
|
|
|
|
if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
|
|
pam_syslog(idata->pamh, LOG_ERR,
|
|
@@ -1259,7 +1259,7 @@ static int create_polydir(struct polydir
|
|
}
|
|
#endif
|
|
|
|
- rc = protect_dir(dir, mode, 1, idata->flags & PAMNS_MOUNT_PRIVATE, idata);
|
|
+ rc = protect_dir(dir, mode, 1, idata);
|
|
if (rc == -1) {
|
|
pam_syslog(idata->pamh, LOG_ERR,
|
|
"Error creating directory %s: %m", dir);
|
|
@@ -1447,7 +1447,7 @@ static int ns_setup(struct polydir_s *po
|
|
pam_syslog(idata->pamh, LOG_DEBUG,
|
|
"Set namespace for directory %s", polyptr->dir);
|
|
|
|
- retval = protect_dir(polyptr->dir, 0, 0, idata->flags & PAMNS_MOUNT_PRIVATE, idata);
|
|
+ retval = protect_dir(polyptr->dir, 0, 0, idata);
|
|
|
|
if (retval < 0 && errno != ENOENT) {
|
|
pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
|
|
@@ -1534,22 +1534,6 @@ static int ns_setup(struct polydir_s *po
|
|
goto error_out;
|
|
}
|
|
|
|
- if (idata->flags & PAMNS_MOUNT_PRIVATE) {
|
|
- /*
|
|
- * Make the polyinstantiated dir private mount. This depends
|
|
- * on making the dir a mount point in the protect_dir call.
|
|
- */
|
|
- if (mount(polyptr->dir, polyptr->dir, NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
|
|
- pam_syslog(idata->pamh, LOG_ERR, "Error making %s a private mount, %m",
|
|
- polyptr->dir);
|
|
- goto error_out;
|
|
- }
|
|
- if (idata->flags & PAMNS_DEBUG)
|
|
- pam_syslog(idata->pamh, LOG_DEBUG,
|
|
- "Polyinstantiated directory %s made as private mount", polyptr->dir);
|
|
-
|
|
- }
|
|
-
|
|
/*
|
|
* Bind mount instance directory on top of the polyinstantiated
|
|
* directory to provide an instance of polyinstantiated directory
|
|
@@ -1720,6 +1704,18 @@ static int setup_namespace(struct instan
|
|
"Unable to unshare from parent namespace, %m");
|
|
return PAM_SESSION_ERR;
|
|
}
|
|
+ if (idata->flags & PAMNS_MOUNT_PRIVATE) {
|
|
+ /* Remount / as SLAVE so that nothing mounted in the namespace
|
|
+ shows up in the parent */
|
|
+ if (mount("/", "/", NULL, MS_SLAVE | MS_REC , NULL) < 0) {
|
|
+ pam_syslog(idata->pamh, LOG_ERR,
|
|
+ "Failed to mark / as a slave mount point, %m");
|
|
+ return PAM_SESSION_ERR;
|
|
+ }
|
|
+ if (idata->flags & PAMNS_DEBUG)
|
|
+ pam_syslog(idata->pamh, LOG_DEBUG,
|
|
+ "The / mount point was marked as slave");
|
|
+ }
|
|
} else {
|
|
del_polydir_list(idata->polydirs_ptr);
|
|
return PAM_SUCCESS;
|