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>
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);
}
}
- 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;
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,
}
#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);
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",
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
"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;