summaryrefslogtreecommitdiff
path: root/modules/pam_namespace
diff options
context:
space:
mode:
authorSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 17:53:41 -0800
committerSteve Langasek <steve.langasek@ubuntu.com>2019-01-03 18:17:08 -0800
commit212b52cf29c06cc209bc8ac0540dbab1acdf1464 (patch)
tree58da0bf39f5c4122e4a1b4da20fdeea52b97a671 /modules/pam_namespace
parent9c52e721044e7501c3d4567b36d222dc7326224a (diff)
parent56c8282d128fb484ffc77dff73abf42229b291d3 (diff)
New upstream version 1.1.0
Diffstat (limited to 'modules/pam_namespace')
-rw-r--r--modules/pam_namespace/Makefile.in81
-rw-r--r--modules/pam_namespace/README15
-rw-r--r--modules/pam_namespace/namespace.conf.5266
-rw-r--r--modules/pam_namespace/namespace.conf.5.xml4
-rw-r--r--modules/pam_namespace/pam_namespace.8272
-rw-r--r--modules/pam_namespace/pam_namespace.8.xml22
-rw-r--r--modules/pam_namespace/pam_namespace.c432
-rw-r--r--modules/pam_namespace/pam_namespace.h8
8 files changed, 834 insertions, 266 deletions
diff --git a/modules/pam_namespace/Makefile.in b/modules/pam_namespace/Makefile.in
index 0ca27c83..9609fc0a 100644
--- a/modules/pam_namespace/Makefile.in
+++ b/modules/pam_namespace/Makefile.in
@@ -1,4 +1,4 @@
-# Makefile.in generated by automake 1.10.1 from Makefile.am.
+# Makefile.in generated by automake 1.10.2 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
@@ -41,17 +41,20 @@ build_triplet = @build@
host_triplet = @host@
@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
subdir = modules/pam_namespace
-DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \
+DIST_COMMON = README $(noinst_HEADERS) $(srcdir)/Makefile.am \
$(srcdir)/Makefile.in
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \
- $(top_srcdir)/m4/iconv.m4 \
+ $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \
+ $(top_srcdir)/m4/japhar_grep_cflags.m4 \
$(top_srcdir)/m4/jh_path_xml_catalog.m4 \
$(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \
$(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \
$(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \
- $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \
- $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \
+ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \
+ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \
+ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \
+ $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \
$(top_srcdir)/configure.in
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
@@ -116,23 +119,19 @@ CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
-CXX = @CXX@
-CXXCPP = @CXXCPP@
-CXXDEPMODE = @CXXDEPMODE@
-CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DSYMUTIL = @DSYMUTIL@
-ECHO = @ECHO@
+DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
-F77 = @F77@
-FFLAGS = @FFLAGS@
+FGREP = @FGREP@
FO2PDF = @FO2PDF@
+GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@
GMSGFMT = @GMSGFMT@
GMSGFMT_015 = @GMSGFMT_015@
GREP = @GREP@
@@ -144,6 +143,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
INTLLIBS = @INTLLIBS@
INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LD = @LD@
LDFLAGS = @LDFLAGS@
LEX = @LEX@
LEXLIB = @LEXLIB@
@@ -167,6 +167,7 @@ LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
LIBS = @LIBS@
LIBSELINUX = @LIBSELINUX@
LIBTOOL = @LIBTOOL@
+LIPO = @LIPO@
LN_S = @LN_S@
LTLIBICONV = @LTLIBICONV@
LTLIBINTL = @LTLIBINTL@
@@ -176,15 +177,18 @@ MKDIR_P = @MKDIR_P@
MSGFMT = @MSGFMT@
MSGFMT_015 = @MSGFMT_015@
MSGMERGE = @MSGMERGE@
+NM = @NM@
NMEDIT = @NMEDIT@
+OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
+OTOOL = @OTOOL@
+OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_VERSION = @PACKAGE_VERSION@
-PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@
PATH_SEPARATOR = @PATH_SEPARATOR@
PIE_CFLAGS = @PIE_CFLAGS@
PIE_LDFLAGS = @PIE_LDFLAGS@
@@ -198,10 +202,9 @@ SHELL = @SHELL@
STRIP = @STRIP@
USE_NLS = @USE_NLS@
VERSION = @VERSION@
-WITH_DEBUG = @WITH_DEBUG@
-WITH_PAMLOCKING = @WITH_PAMLOCKING@
XGETTEXT = @XGETTEXT@
XGETTEXT_015 = @XGETTEXT_015@
+XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@
XMLCATALOG = @XMLCATALOG@
XMLLINT = @XMLLINT@
XML_CATALOG_FILE = @XML_CATALOG_FILE@
@@ -213,8 +216,7 @@ abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_CC = @ac_ct_CC@
-ac_ct_CXX = @ac_ct_CXX@
-ac_ct_F77 = @ac_ct_F77@
+ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
@@ -246,6 +248,7 @@ libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
+lt_ECHO = @lt_ECHO@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
@@ -260,6 +263,7 @@ sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
+top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
CLEANFILES = *~
@@ -292,8 +296,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
- cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \
- && exit 0; \
+ ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
+ && { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
@@ -413,8 +417,8 @@ install-man5: $(man5_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
5*) ;; \
@@ -458,8 +462,8 @@ install-man8: $(man8_MANS) $(man_MANS)
esac; \
done; \
for i in $$list; do \
- if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
- else file=$$i; fi; \
+ if test -f $$i; then file=$$i; \
+ else file=$(srcdir)/$$i; fi; \
ext=`echo $$i | sed -e 's/^.*\\.//'`; \
case "$$ext" in \
8*) ;; \
@@ -532,7 +536,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | \
- $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \
+ $(AWK) '{ files[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in files) print i; }; }'`; \
mkid -fID $$unique
tags: TAGS
@@ -575,7 +579,7 @@ distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
check-TESTS: $(TESTS)
- @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \
+ @failed=0; all=0; xfail=0; xpass=0; skip=0; \
srcdir=$(srcdir); export srcdir; \
list=' $(TESTS) '; \
if test -n "$$list"; then \
@@ -586,7 +590,7 @@ check-TESTS: $(TESTS)
if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
+ *[\ \ ]$$tst[\ \ ]*) \
xpass=`expr $$xpass + 1`; \
failed=`expr $$failed + 1`; \
echo "XPASS: $$tst"; \
@@ -598,7 +602,7 @@ check-TESTS: $(TESTS)
elif test $$? -ne 77; then \
all=`expr $$all + 1`; \
case " $(XFAIL_TESTS) " in \
- *$$ws$$tst$$ws*) \
+ *[\ \ ]$$tst[\ \ ]*) \
xfail=`expr $$xfail + 1`; \
echo "XFAIL: $$tst"; \
;; \
@@ -612,23 +616,36 @@ check-TESTS: $(TESTS)
echo "SKIP: $$tst"; \
fi; \
done; \
+ if test "$$all" -eq 1; then \
+ tests="test"; \
+ All=""; \
+ else \
+ tests="tests"; \
+ All="All "; \
+ fi; \
if test "$$failed" -eq 0; then \
if test "$$xfail" -eq 0; then \
- banner="All $$all tests passed"; \
+ banner="$$All$$all $$tests passed"; \
else \
- banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \
+ banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \
fi; \
else \
if test "$$xpass" -eq 0; then \
- banner="$$failed of $$all tests failed"; \
+ banner="$$failed of $$all $$tests failed"; \
else \
- banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \
+ if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \
+ banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \
fi; \
fi; \
dashes="$$banner"; \
skipped=""; \
if test "$$skip" -ne 0; then \
- skipped="($$skip tests were not run)"; \
+ if test "$$skip" -eq 1; then \
+ skipped="($$skip test was not run)"; \
+ else \
+ skipped="($$skip tests were not run)"; \
+ fi; \
test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
dashes="$$skipped"; \
fi; \
diff --git a/modules/pam_namespace/README b/modules/pam_namespace/README
index 13c9c45b..8259051b 100644
--- a/modules/pam_namespace/README
+++ b/modules/pam_namespace/README
@@ -8,10 +8,11 @@ The pam_namespace PAM module sets up a private namespace for a session with
polyinstantiated directories. A polyinstantiated directory provides a different
instance of itself based on user name, or when using SELinux, user name,
security context or both. If an executable script /etc/security/namespace.init
-exists, it is used to initialize the namespace every time a new instance
-directory is setup. The script receives the polyinstantiated directory path,
-the instance directory path, flag whether the instance directory was newly
-created (0 for no, 1 for yes), and the user name as its arguments.
+exists, it is used to initialize the instance directory after it is set up and
+mounted on the polyinstantiated direcory. The script receives the
+polyinstantiated directory path, the instance directory path, flag whether the
+instance directory was newly created (0 for no, 1 for yes), and the user name
+as its arguments.
The pam_namespace module disassociates the session namespace from the parent
namespace. Any mounts/unmounts performed in the parent namespace, such as
@@ -92,9 +93,9 @@ The pam_namespace.so module allows setup of private namespaces with
polyinstantiated directories. Directories can be polyinstantiated based on user
name or, in the case of SELinux, user name, sensitivity level or complete
security context. If an executable script /etc/security/namespace.init exists,
-it is used to initialize the namespace every time a new instance directory is
-setup. The script receives the polyinstantiated directory path and the instance
-directory path as its arguments.
+it is used to initialize the namespace every time an instance directory is set
+up and mounted. The script receives the polyinstantiated directory path and the
+instance directory path as its arguments.
The /etc/security/namespace.conf file specifies which directories are
polyinstantiated, how they are polyinstantiated, how instance directories would
diff --git a/modules/pam_namespace/namespace.conf.5 b/modules/pam_namespace/namespace.conf.5
index 9e293dbd..7db2c833 100644
--- a/modules/pam_namespace/namespace.conf.5
+++ b/modules/pam_namespace/namespace.conf.5
@@ -1,40 +1,196 @@
.\" Title: namespace.conf
-.\" Author:
-.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
-.\" Date: 04/16/2008
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/>
+.\" Date: 03/02/2009
.\" Manual: Linux-PAM Manual
.\" Source: Linux-PAM Manual
+.\" Language: English
.\"
-.TH "NAMESPACE\.CONF" "5" "04/16/2008" "Linux-PAM Manual" "Linux\-PAM Manual"
+.TH "NAMESPACE\&.CONF" "5" "03/02/2009" "Linux-PAM Manual" "Linux\-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * (re)Define some macros
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" toupper - uppercase a string (locale-aware)
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de toupper
+.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
+\\$*
+.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SH-xref - format a cross-reference to an SH section
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de SH-xref
+.ie n \{\
+.\}
+.toupper \\$*
+.el \{\
+\\$*
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SH - level-one heading that works better for non-TTY output
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de1 SH
+.\" put an extra blank line of space above the head in non-TTY output
+.if t \{\
+.sp 1
+.\}
+.sp \\n[PD]u
+.nr an-level 1
+.set-an-margin
+.nr an-prevailing-indent \\n[IN]
+.fi
+.in \\n[an-margin]u
+.ti 0
+.HTML-TAG ".NH \\n[an-level]"
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+\." make the size of the head bigger
+.ps +3
+.ft B
+.ne (2v + 1u)
+.ie n \{\
+.\" if n (TTY output), use uppercase
+.toupper \\$*
+.\}
+.el \{\
+.nr an-break-flag 0
+.\" if not n (not TTY), use normal case (not uppercase)
+\\$1
+.in \\n[an-margin]u
+.ti 0
+.\" if not n (not TTY), put a border/line under subheading
+.sp -.6
+\l'\n(.lu'
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SS - level-two heading that works better for non-TTY output
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de1 SS
+.sp \\n[PD]u
+.nr an-level 1
+.set-an-margin
+.nr an-prevailing-indent \\n[IN]
+.fi
+.in \\n[IN]u
+.ti \\n[SN]u
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.ps \\n[PS-SS]u
+\." make the size of the head bigger
+.ps +2
+.ft B
+.ne (2v + 1u)
+.if \\n[.$] \&\\$*
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" BB/BE - put background/screen (filled box) around block of text
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de BB
+.if t \{\
+.sp -.5
+.br
+.in +2n
+.ll -2n
+.gcolor red
+.di BX
+.\}
+..
+.de EB
+.if t \{\
+.if "\\$2"adjust-for-leading-newline" \{\
+.sp -1
+.\}
+.br
+.di
+.in
+.ll
+.gcolor
+.nr BW \\n(.lu-\\n(.i
+.nr BH \\n(dn+.5v
+.ne \\n(BHu+.5v
+.ie "\\$2"adjust-for-leading-newline" \{\
+\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
+.\}
+.el \{\
+\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
+.\}
+.in 0
+.sp -.5v
+.nf
+.BX
+.in
+.sp .5v
+.fi
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" BM/EM - put colored marker in margin next to block of text
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de BM
+.if t \{\
+.br
+.ll -2n
+.gcolor red
+.di BX
+.\}
+..
+.de EM
+.if t \{\
+.br
+.di
+.ll
+.gcolor
+.nr BH \\n(dn
+.ne \\n(BHu
+\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[]
+.in 0
+.nf
+.BX
+.in
+.fi
+.\}
+..
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
-.SH "NAME"
-namespace.conf - the namespace configuration file
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "Name"
+namespace.conf \- the namespace configuration file
.SH "DESCRIPTION"
.PP
The
-\fIpam_namespace\.so\fR
-module allows setup of private namespaces with polyinstantiated directories\. Directories can be polyinstantiated based on user name or, in the case of SELinux, user name, sensitivity level or complete security context\. If an executable script
-\fI/etc/security/namespace\.init\fR
-exists, it is used to initialize the namespace every time a new instance directory is setup\. The script receives the polyinstantiated directory path and the instance directory path as its arguments\.
+\fIpam_namespace\&.so\fR
+module allows setup of private namespaces with polyinstantiated directories\&. Directories can be polyinstantiated based on user name or, in the case of SELinux, user name, sensitivity level or complete security context\&. If an executable script
+\FC/etc/security/namespace\&.init\F[]
+exists, it is used to initialize the namespace every time an instance directory is set up and mounted\&. The script receives the polyinstantiated directory path and the instance directory path as its arguments\&.
.PP
The
-\fI/etc/security/namespace\.conf\fR
-file specifies which directories are polyinstantiated, how they are polyinstantiated, how instance directories would be named, and any users for whom polyinstantiation would not be performed\.
+\FC/etc/security/namespace\&.conf\F[]
+file specifies which directories are polyinstantiated, how they are polyinstantiated, how instance directories would be named, and any users for whom polyinstantiation would not be performed\&.
.PP
When someone logs in, the file
-\fInamespace\.conf\fR
-is scanned\. Comments are marked by
+\FCnamespace\&.conf\F[]
+is scanned\&. Comments are marked by
\fI#\fR
-characters\. Each non comment line represents one polyinstantiated directory\. The fields are separated by spaces but can be quoted by
+characters\&. Each non comment line represents one polyinstantiated directory\&. The fields are separated by spaces but can be quoted by
\fI"\fR
characters also escape sequences
\fI\eb\fR,
\fI\en\fR, and
\fI\et\fR
-are recognized\. The fields are as follows:
+are recognized\&. The fields are as follows:
.PP
\fIpolydir\fR
\fIinstance_prefix\fR
@@ -42,92 +198,110 @@ are recognized\. The fields are as follows:
\fIlist_of_uids\fR
.PP
The first field,
-\fIpolydir\fR, is the absolute pathname of the directory to polyinstantiate\. The special string
+\fIpolydir\fR, is the absolute pathname of the directory to polyinstantiate\&. The special string
\fI$HOME\fR
is replaced with the user\'s home directory, and
\fI$USER\fR
-with the username\. This field cannot be blank\.
+with the username\&. This field cannot be blank\&.
.PP
The second field,
\fIinstance_prefix\fR
-is the string prefix used to build the pathname for the instantiation of <polydir>\. Depending on the polyinstantiation
+is the string prefix used to build the pathname for the instantiation of <polydir>\&. Depending on the polyinstantiation
\fImethod\fR
-it is then appended with "instance differentiation string" to generate the final instance directory path\. This directory is created if it did not exist already, and is then bind mounted on the <polydir> to provide an instance of <polydir> based on the <method> column\. The special string
+it is then appended with "instance differentiation string" to generate the final instance directory path\&. This directory is created if it did not exist already, and is then bind mounted on the <polydir> to provide an instance of <polydir> based on the <method> column\&. The special string
\fI$HOME\fR
is replaced with the user\'s home directory, and
\fI$USER\fR
-with the username\. This field cannot be blank\.
+with the username\&. This field cannot be blank\&.
.PP
The third field,
-\fImethod\fR, is the method used for polyinstantiation\. It can take these values; "user" for polyinstantiation based on user name, "level" for polyinstantiation based on process MLS level and user name, "context" for polyinstantiation based on process security context and user name, "tmpfs" for mounting tmpfs filesystem as an instance dir, and "tmpdir" for creating temporary directory as an instance dir which is removed when the user\'s session is closed\. Methods "context" and "level" are only available with SELinux\. This field cannot be blank\.
+\fImethod\fR, is the method used for polyinstantiation\&. It can take these values; "user" for polyinstantiation based on user name, "level" for polyinstantiation based on process MLS level and user name, "context" for polyinstantiation based on process security context and user name, "tmpfs" for mounting tmpfs filesystem as an instance dir, and "tmpdir" for creating temporary directory as an instance dir which is removed when the user\'s session is closed\&. Methods "context" and "level" are only available with SELinux\&. This field cannot be blank\&.
.PP
The fourth field,
-\fIlist_of_uids\fR, is a comma separated list of user names for whom the polyinstantiation is not performed\. If left blank, polyinstantiation will be performed for all users\. If the list is preceded with a single "~" character, polyinstantiation is performed only for users in the list\.
+\fIlist_of_uids\fR, is a comma separated list of user names for whom the polyinstantiation is not performed\&. If left blank, polyinstantiation will be performed for all users\&. If the list is preceded with a single "~" character, polyinstantiation is performed only for users in the list\&.
.PP
The
\fImethod\fR
field can contain also following optional flags separated by
\fI:\fR
-characters\.
+characters\&.
.PP
\fIcreate\fR=\fImode\fR,\fIowner\fR,\fIgroup\fR
-\- create the polyinstantiated directory\. The mode, owner and group parameters are optional\. The default for mode is determined by umask, the default owner is the user whose session is opened, the default group is the primary group of the user\.
+\- create the polyinstantiated directory\&. The mode, owner and group parameters are optional\&. The default for mode is determined by umask, the default owner is the user whose session is opened, the default group is the primary group of the user\&.
.PP
\fIiscript\fR=\fIpath\fR
-\- path to the instance directory init script\. The base directory for relative paths is
-\fI/etc/security/namespace\.d\fR\.
+\- path to the instance directory init script\&. The base directory for relative paths is
+\FC/etc/security/namespace\&.d\F[]\&.
.PP
\fInoinit\fR
-\- instance directory init script will not be executed\.
+\- instance directory init script will not be executed\&.
.PP
\fIshared\fR
-\- the instance directories for "context" and "level" methods will not contain the user name and will be shared among all users\.
+\- the instance directories for "context" and "level" methods will not contain the user name and will be shared among all users\&.
.PP
-The directory where polyinstantiated instances are to be created, must exist and must have, by default, the mode of 0000\. The requirement that the instance parent be of mode 0000 can be overridden with the command line option
+The directory where polyinstantiated instances are to be created, must exist and must have, by default, the mode of 0000\&. The requirement that the instance parent be of mode 0000 can be overridden with the command line option
\fIignore_instance_parent_mode\fR
.PP
-In case of context or level polyinstantiation the SELinux context which is used for polyinstantiation is the context used for executing a new process as obtained by getexeccon\. This context must be set by the calling application or
-\fIpam_selinux\.so\fR
-module\. If this context is not set the polyinstatiation will be based just on user name\.
+In case of context or level polyinstantiation the SELinux context which is used for polyinstantiation is the context used for executing a new process as obtained by getexeccon\&. This context must be set by the calling application or
+\FCpam_selinux\&.so\F[]
+module\&. If this context is not set the polyinstatiation will be based just on user name\&.
.PP
-The "instance differentiation string" is <user name> for "user" method and <user name>_<raw directory context> for "context" and "level" methods\. If the whole string is too long the end of it is replaced with md5sum of itself\. Also when command line option
+The "instance differentiation string" is <user name> for "user" method and <user name>_<raw directory context> for "context" and "level" methods\&. If the whole string is too long the end of it is replaced with md5sum of itself\&. Also when command line option
\fIgen_hash\fR
-is used the whole string is replaced with md5sum of itself\.
+is used the whole string is replaced with md5sum of itself\&.
.SH "EXAMPLES"
.PP
These are some example lines which might be specified in
-\fI/etc/security/namespace\.conf\fR\.
+\FC/etc/security/namespace\&.conf\F[]\&.
.sp
+.if n \{\
.RS 4
+.\}
+.fam C
+.ps -1
.nf
+.if t \{\
+.sp -1
+.\}
+.BB lightgray adjust-for-leading-newline
+.sp -1
+
# The following three lines will polyinstantiate /tmp,
- # /var/tmp and user\'s home directories\. /tmp and /var/tmp
+ # /var/tmp and user\'s home directories\&. /tmp and /var/tmp
# will be polyinstantiated based on the security level
# as well as user name, whereas home directory will be
- # polyinstantiated based on the full security context and user name\.
+ # polyinstantiated based on the full security context and user name\&.
# Polyinstantiation will not be performed for user root
# and adm for directories /tmp and /var/tmp, whereas home
- # directories will be polyinstantiated for all users\.
+ # directories will be polyinstantiated for all users\&.
#
# Note that instance directories do not have to reside inside
- # the polyinstantiated directory\. In the examples below,
+ # the polyinstantiated directory\&. In the examples below,
# instances of /tmp will be created in /tmp\-inst directory,
# where as instances of /var/tmp and users home directories
# will reside within the directories that are being
- # polyinstantiated\.
+ # polyinstantiated\&.
#
/tmp /tmp\-inst/ level root,adm
/var/tmp /var/tmp/tmp\-inst/ level root,adm
- $HOME $HOME/$USER\.inst/inst\- context
+ $HOME $HOME/$USER\&.inst/inst\- context
+.EB lightgray adjust-for-leading-newline
+.if t \{\
+.sp 1
+.\}
.fi
+.fam
+.ps +1
+.if n \{\
.RE
+.\}
.PP
-For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\.d/<service> as the last line for session group:
+For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\&.d/<service> as the last line for session group:
.PP
-session required pam_namespace\.so [arguments]
+session required pam_namespace\&.so [arguments]
.PP
-This module also depends on pam_selinux\.so setting the context\.
+This module also depends on pam_selinux\&.so setting the context\&.
.SH "SEE ALSO"
.PP
@@ -136,4 +310,4 @@ This module also depends on pam_selinux\.so setting the context\.
\fBpam\fR(8)
.SH "AUTHORS"
.PP
-The namespace\.conf manual page was written by Janak Desai <janak@us\.ibm\.com>\. More features added by Tomas Mraz <tmraz@redhat\.com>\.
+The namespace\&.conf manual page was written by Janak Desai <janak@us\&.ibm\&.com>\&. More features added by Tomas Mraz <tmraz@redhat\&.com>\&.
diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml
index a1769600..61c8673b 100644
--- a/modules/pam_namespace/namespace.conf.5.xml
+++ b/modules/pam_namespace/namespace.conf.5.xml
@@ -25,8 +25,8 @@
Directories can be polyinstantiated based on user name
or, in the case of SELinux, user name, sensitivity level or complete security context. If an
executable script <filename>/etc/security/namespace.init</filename>
- exists, it is used to initialize the namespace every time a new instance
- directory is setup. The script receives the polyinstantiated
+ exists, it is used to initialize the namespace every time an instance
+ directory is set up and mounted. The script receives the polyinstantiated
directory path and the instance directory path as its arguments.
</para>
diff --git a/modules/pam_namespace/pam_namespace.8 b/modules/pam_namespace/pam_namespace.8
index 485e06b5..92660ff2 100644
--- a/modules/pam_namespace/pam_namespace.8
+++ b/modules/pam_namespace/pam_namespace.8
@@ -1,27 +1,185 @@
.\" Title: pam_namespace
-.\" Author:
-.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/>
-.\" Date: 04/16/2008
+.\" Author: [see the "AUTHORS" section]
+.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/>
+.\" Date: 06/16/2009
.\" Manual: Linux-PAM Manual
.\" Source: Linux-PAM Manual
+.\" Language: English
.\"
-.TH "PAM_NAMESPACE" "8" "04/16/2008" "Linux-PAM Manual" "Linux-PAM Manual"
+.TH "PAM_NAMESPACE" "8" "06/16/2009" "Linux-PAM Manual" "Linux-PAM Manual"
+.\" -----------------------------------------------------------------
+.\" * (re)Define some macros
+.\" -----------------------------------------------------------------
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" toupper - uppercase a string (locale-aware)
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de toupper
+.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
+\\$*
+.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SH-xref - format a cross-reference to an SH section
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de SH-xref
+.ie n \{\
+.\}
+.toupper \\$*
+.el \{\
+\\$*
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SH - level-one heading that works better for non-TTY output
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de1 SH
+.\" put an extra blank line of space above the head in non-TTY output
+.if t \{\
+.sp 1
+.\}
+.sp \\n[PD]u
+.nr an-level 1
+.set-an-margin
+.nr an-prevailing-indent \\n[IN]
+.fi
+.in \\n[an-margin]u
+.ti 0
+.HTML-TAG ".NH \\n[an-level]"
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+\." make the size of the head bigger
+.ps +3
+.ft B
+.ne (2v + 1u)
+.ie n \{\
+.\" if n (TTY output), use uppercase
+.toupper \\$*
+.\}
+.el \{\
+.nr an-break-flag 0
+.\" if not n (not TTY), use normal case (not uppercase)
+\\$1
+.in \\n[an-margin]u
+.ti 0
+.\" if not n (not TTY), put a border/line under subheading
+.sp -.6
+\l'\n(.lu'
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" SS - level-two heading that works better for non-TTY output
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de1 SS
+.sp \\n[PD]u
+.nr an-level 1
+.set-an-margin
+.nr an-prevailing-indent \\n[IN]
+.fi
+.in \\n[IN]u
+.ti \\n[SN]u
+.it 1 an-trap
+.nr an-no-space-flag 1
+.nr an-break-flag 1
+.ps \\n[PS-SS]u
+\." make the size of the head bigger
+.ps +2
+.ft B
+.ne (2v + 1u)
+.if \\n[.$] \&\\$*
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" BB/BE - put background/screen (filled box) around block of text
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de BB
+.if t \{\
+.sp -.5
+.br
+.in +2n
+.ll -2n
+.gcolor red
+.di BX
+.\}
+..
+.de EB
+.if t \{\
+.if "\\$2"adjust-for-leading-newline" \{\
+.sp -1
+.\}
+.br
+.di
+.in
+.ll
+.gcolor
+.nr BW \\n(.lu-\\n(.i
+.nr BH \\n(dn+.5v
+.ne \\n(BHu+.5v
+.ie "\\$2"adjust-for-leading-newline" \{\
+\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
+.\}
+.el \{\
+\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
+.\}
+.in 0
+.sp -.5v
+.nf
+.BX
+.in
+.sp .5v
+.fi
+.\}
+..
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.\" BM/EM - put colored marker in margin next to block of text
+.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+.de BM
+.if t \{\
+.br
+.ll -2n
+.gcolor red
+.di BX
+.\}
+..
+.de EM
+.if t \{\
+.br
+.di
+.ll
+.gcolor
+.nr BH \\n(dn
+.ne \\n(BHu
+\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[]
+.in 0
+.nf
+.BX
+.in
+.fi
+.\}
+..
+.\" -----------------------------------------------------------------
+.\" * set default formatting
+.\" -----------------------------------------------------------------
.\" disable hyphenation
.nh
.\" disable justification (adjust text to left margin only)
.ad l
-.SH "NAME"
-pam_namespace - PAM module for configuring namespace for a session
-.SH "SYNOPSIS"
-.HP 17
-\fBpam_namespace\.so\fR [debug] [unmnt_remnt] [unmnt_only] [require_selinux] [gen_hash] [ignore_config_error] [ignore_instance_parent_mode] [no_unmount_on_close] [use_current_context] [use_default_context]
+.\" -----------------------------------------------------------------
+.\" * MAIN CONTENT STARTS HERE *
+.\" -----------------------------------------------------------------
+.SH "Name"
+pam_namespace \- PAM module for configuring namespace for a session
+.SH "Synopsis"
+.fam C
+.HP \w'\fBpam_namespace\&.so\fR\ 'u
+\fBpam_namespace\&.so\fR [debug] [unmnt_remnt] [unmnt_only] [require_selinux] [gen_hash] [ignore_config_error] [ignore_instance_parent_mode] [no_unmount_on_close] [use_current_context] [use_default_context]
+.fam
.SH "DESCRIPTION"
.PP
-The pam_namespace PAM module sets up a private namespace for a session with polyinstantiated directories\. A polyinstantiated directory provides a different instance of itself based on user name, or when using SELinux, user name, security context or both\. If an executable script
-\fI/etc/security/namespace\.init\fR
-exists, it is used to initialize the namespace every time a new instance directory is setup\. The script receives the polyinstantiated directory path, the instance directory path, flag whether the instance directory was newly created (0 for no, 1 for yes), and the user name as its arguments\.
+The pam_namespace PAM module sets up a private namespace for a session with polyinstantiated directories\&. A polyinstantiated directory provides a different instance of itself based on user name, or when using SELinux, user name, security context or both\&. If an executable script
+\FC/etc/security/namespace\&.init\F[]
+exists, it is used to initialize the instance directory after it is set up and mounted on the polyinstantiated directory\&. The script receives the polyinstantiated directory path, the instance directory path, flag whether the instance directory was newly created (0 for no, 1 for yes), and the user name as its arguments\&.
.PP
-The pam_namespace module disassociates the session namespace from the parent namespace\. Any mounts/unmounts performed in the parent namespace, such as mounting of devices, are not reflected in the session namespace\. To propagate selected mount/unmount events from the parent namespace into the disassociated session namespace, an administrator may use the special shared\-subtree feature\. For additional information on shared\-subtree feature, please refer to the mount(8) man page and the shared\-subtree description at http://lwn\.net/Articles/159077 and http://lwn\.net/Articles/159092\.
+The pam_namespace module disassociates the session namespace from the parent namespace\&. Any mounts/unmounts performed in the parent namespace, such as mounting of devices, are not reflected in the session namespace\&. To propagate selected mount/unmount events from the parent namespace into the disassociated session namespace, an administrator may use the special shared\-subtree feature\&. For additional information on shared\-subtree feature, please refer to the mount(8) man page and the shared\-subtree description at http://lwn\&.net/Articles/159077 and http://lwn\&.net/Articles/159092\&.
.SH "OPTIONS"
.PP
\fBdebug\fR
@@ -31,7 +189,7 @@ A lot of debug information is logged using syslog
.PP
\fBunmnt_remnt\fR
.RS 4
-For programs such as su and newrole, the login session has already setup a polyinstantiated namespace\. For these programs, polyinstantiation is performed based on new user id or security context, however the command first needs to undo the polyinstantiation performed by login\. This argument instructs the command to first undo previous polyinstantiation before proceeding with new polyinstantiation based on new id/context
+For programs such as su and newrole, the login session has already setup a polyinstantiated namespace\&. For these programs, polyinstantiation is performed based on new user id or security context, however the command first needs to undo the polyinstantiation performed by login\&. This argument instructs the command to first undo previous polyinstantiation before proceeding with new polyinstantiation based on new id/context
.RE
.PP
\fBunmnt_only\fR
@@ -46,112 +204,130 @@ If selinux is not enabled, return failure
.PP
\fBgen_hash\fR
.RS 4
-Instead of using the security context string for the instance name, generate and use its md5 hash\.
+Instead of using the security context string for the instance name, generate and use its md5 hash\&.
.RE
.PP
\fBignore_config_error\fR
.RS 4
-If a line in the configuration file corresponding to a polyinstantiated directory contains format error, skip that line process the next line\. Without this option, pam will return an error to the calling program resulting in termination of the session\.
+If a line in the configuration file corresponding to a polyinstantiated directory contains format error, skip that line process the next line\&. Without this option, pam will return an error to the calling program resulting in termination of the session\&.
.RE
.PP
\fBignore_instance_parent_mode\fR
.RS 4
-Instance parent directories by default are expected to have the restrictive mode of 000\. Using this option, an administrator can choose to ignore the mode of the instance parent\. This option should be used with caution as it will reduce security and isolation goals of the polyinstantiation mechanism\.
+Instance parent directories by default are expected to have the restrictive mode of 000\&. Using this option, an administrator can choose to ignore the mode of the instance parent\&. This option should be used with caution as it will reduce security and isolation goals of the polyinstantiation mechanism\&.
.RE
.PP
\fBno_unmount_on_close\fR
.RS 4
-For certain trusted programs such as newrole, open session is called from a child process while the parent perfoms close session and pam end functions\. For these commands use this option to instruct pam_close_session to not unmount the bind mounted polyinstantiated directory in the parent\.
+For certain trusted programs such as newrole, open session is called from a child process while the parent performs close session and pam end functions\&. For these commands use this option to instruct pam_close_session to not unmount the bind mounted polyinstantiated directory in the parent\&.
.RE
.PP
\fBuse_current_context\fR
.RS 4
-Useful for services which do not change the SELinux context with setexeccon call\. The module will use the current SELinux context of the calling process for the level and context polyinstantiation\.
+Useful for services which do not change the SELinux context with setexeccon call\&. The module will use the current SELinux context of the calling process for the level and context polyinstantiation\&.
.RE
.PP
\fBuse_default_context\fR
.RS 4
-Useful for services which do not use pam_selinux for changing the SELinux context with setexeccon call\. The module will use the default SELinux context of the user for the level and context polyinstantiation\.
+Useful for services which do not use pam_selinux for changing the SELinux context with setexeccon call\&. The module will use the default SELinux context of the user for the level and context polyinstantiation\&.
.RE
-.SH "MODULE SERVICES PROVIDED"
+.SH "MODULE TYPES PROVIDED"
.PP
-The
+Only the
\fBsession\fR
-service is supported\. The module must not be called from multithreaded processes\.
+module type is provided\&. The module must not be called from multithreaded processes\&.
.SH "RETURN VALUES"
.PP
PAM_SUCCESS
.RS 4
-Namespace setup was successful\.
+Namespace setup was successful\&.
.RE
.PP
PAM_SERVICE_ERR
.RS 4
-Unexpected system error occurred while setting up namespace\.
+Unexpected system error occurred while setting up namespace\&.
.RE
.PP
PAM_SESSION_ERR
.RS 4
-Unexpected namespace configuration error occurred\.
+Unexpected namespace configuration error occurred\&.
.RE
.SH "FILES"
.PP
-\fI/etc/security/namespace\.conf\fR
+\FC/etc/security/namespace\&.conf\F[]
.RS 4
Main configuration file
.RE
.PP
-\fI/etc/security/namespace\.d\fR
+\FC/etc/security/namespace\&.d\F[]
.RS 4
Directory for additional configuration files
.RE
.PP
-\fI/etc/security/namespace\.init\fR
+\FC/etc/security/namespace\&.init\F[]
.RS 4
Init script for instance directories
.RE
.SH "EXAMPLES"
.PP
-For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\.d/<service> as the last line for session group:
+For the <service>s you need polyinstantiation (login for example) put the following line in /etc/pam\&.d/<service> as the last line for session group:
.PP
-session required pam_namespace\.so [arguments]
+session required pam_namespace\&.so [arguments]
.PP
To use polyinstantiation with graphical display manager gdm, insert the following line, before exit 0, in /etc/gdm/PostSession/Default:
.PP
/usr/sbin/gdm\-safe\-restart
.PP
-This allows gdm to restart after each session and appropriately adjust namespaces of display manager and the X server\. If polyinstantiation of /tmp is desired along with the graphical environment, then additional configuration changes are needed to address the interaction of X server and font server namespaces with their use of /tmp to create communication sockets\. Please use the initialization script
-\fI/etc/security/namespace\.init\fR
-to ensure that the X server and its clients can appropriately access the communication socket X0\. Please refer to the sample instructions provided in the comment section of the instance initialization script
-\fI/etc/security/namespace\.init\fR\. In addition, perform the following changes to use graphical environment with polyinstantiation of /tmp:
+This allows gdm to restart after each session and appropriately adjust namespaces of display manager and the X server\&. If polyinstantiation of /tmp is desired along with the graphical environment, then additional configuration changes are needed to address the interaction of X server and font server namespaces with their use of /tmp to create communication sockets\&. Please use the initialization script
+\FC/etc/security/namespace\&.init\F[]
+to ensure that the X server and its clients can appropriately access the communication socket X0\&. Please refer to the sample instructions provided in the comment section of the instance initialization script
+\FC/etc/security/namespace\&.init\F[]\&. In addition, perform the following changes to use graphical environment with polyinstantiation of /tmp:
.PP
.sp
+.if n \{\
.RS 4
+.\}
+.fam C
+.ps -1
.nf
- 1\. Disable the use of font server by commenting out "FontPath"
- line in /etc/X11/xorg\.conf\. If you do want to use the font server
+.if t \{\
+.sp -1
+.\}
+.BB lightgray adjust-for-leading-newline
+.sp -1
+
+ 1\&. Disable the use of font server by commenting out "FontPath"
+ line in /etc/X11/xorg\&.conf\&. If you do want to use the font server
then you will have to augment the instance initialization
- script to appropriately provide /tmp/\.font\-unix from the
- polyinstantiated /tmp\.
- 2\. Ensure that the gdm service is setup to use pam_namespace,
- as described above, by modifying /etc/pam\.d/gdm\.
- 3\. Ensure that the display manager is configured to restart X server
- with each new session\. This default setup can be verified by
- making sure that /usr/share/gdm/defaults\.conf contains
+ script to appropriately provide /tmp/\&.font\-unix from the
+ polyinstantiated /tmp\&.
+ 2\&. Ensure that the gdm service is setup to use pam_namespace,
+ as described above, by modifying /etc/pam\&.d/gdm\&.
+ 3\&. Ensure that the display manager is configured to restart X server
+ with each new session\&. This default setup can be verified by
+ making sure that /usr/share/gdm/defaults\&.conf contains
"AlwaysRestartServer=true", and it is not overridden by
- /etc/gdm/custom\.conf\.
+ /etc/gdm/custom\&.conf\&.
+.EB lightgray adjust-for-leading-newline
+.if t \{\
+.sp 1
+.\}
.fi
+.fam
+.ps +1
+.if n \{\
.RE
+.\}
.sp
.SH "SEE ALSO"
.PP
\fBnamespace.conf\fR(5),
-\fBpam.d\fR(8),
+\fBpam.d\fR(5),
\fBmount\fR(8),
-\fBpam\fR(8)\.
+\fBpam\fR(8)\&.
.SH "AUTHORS"
.PP
-The namespace setup scheme was designed by Stephen Smalley, Janak Desai and Chad Sellers\. The pam_namespace PAM module was developed by Janak Desai <janak@us\.ibm\.com>, Chad Sellers <csellers@tresys\.com> and Steve Grubb <sgrubb@redhat\.com>\. Additional improvements by Xavier Toth <txtoth@gmail\.com> and Tomas Mraz <tmraz@redhat\.com>\.
+The namespace setup scheme was designed by Stephen Smalley, Janak Desai and Chad Sellers\&. The pam_namespace PAM module was developed by Janak Desai <janak@us\&.ibm\&.com>, Chad Sellers <csellers@tresys\&.com> and Steve Grubb <sgrubb@redhat\&.com>\&. Additional improvements by Xavier Toth <txtoth@gmail\&.com> and Tomas Mraz <tmraz@redhat\&.com>\&.
diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml
index 32c5359d..0433f0fd 100644
--- a/modules/pam_namespace/pam_namespace.8.xml
+++ b/modules/pam_namespace/pam_namespace.8.xml
@@ -64,11 +64,11 @@
provides a different instance of itself based on user name, or when
using SELinux, user name, security context or both. If an executable
script <filename>/etc/security/namespace.init</filename> exists, it
- is used to initialize the namespace every time a new instance
- directory is setup. The script receives the polyinstantiated
- directory path, the instance directory path, flag whether the instance
- directory was newly created (0 for no, 1 for yes), and the user name
- as its arguments.
+ is used to initialize the instance directory after it is set up
+ and mounted on the polyinstantiated directory. The script receives the
+ polyinstantiated directory path, the instance directory path, flag
+ whether the instance directory was newly created (0 for no, 1 for yes),
+ and the user name as its arguments.
</para>
<para>
@@ -197,7 +197,7 @@
<listitem>
<para>
For certain trusted programs such as newrole, open session
- is called from a child process while the parent perfoms
+ is called from a child process while the parent performs
close session and pam end functions. For these commands
use this option to instruct pam_close_session to not
unmount the bind mounted polyinstantiated directory in the
@@ -237,11 +237,11 @@
</variablelist>
</refsect1>
- <refsect1 id="pam_namespace-services">
- <title>MODULE SERVICES PROVIDED</title>
+ <refsect1 id="pam_namespace-types">
+ <title>MODULE TYPES PROVIDED</title>
<para>
- The <option>session</option> service is supported. The module must not
- be called from multithreaded processes.
+ Only the <option>session</option> module type is provided.
+ The module must not be called from multithreaded processes.
</para>
</refsect1>
@@ -365,7 +365,7 @@
<refentrytitle>namespace.conf</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
- <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
</citerefentry>,
<citerefentry>
<refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index 80c51443..f6219271 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -32,6 +32,8 @@
* DEALINGS IN THE SOFTWARE.
*/
+#define _ATFILE_SOURCE
+
#include "pam_namespace.h"
#include "argv_parse.h"
@@ -78,11 +80,29 @@ static void del_polydir_list(struct polydir_s *polydirs_ptr)
}
}
-static void cleanup_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+static void unprotect_dirs(struct protect_dir_s *dir)
+{
+ struct protect_dir_s *next;
+
+ while (dir != NULL) {
+ umount(dir->dir);
+ free(dir->dir);
+ next = dir->next;
+ free(dir);
+ dir = next;
+ }
+}
+
+static void cleanup_polydir_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
{
del_polydir_list(data);
}
+static void cleanup_protect_data(pam_handle_t *pamh UNUSED , void *data, int err UNUSED)
+{
+ unprotect_dirs(data);
+}
+
static char *expand_variables(const char *orig, const char *var_names[], const char *var_values[])
{
const char *src = orig;
@@ -132,8 +152,8 @@ static char *expand_variables(const char *orig, const char *var_names[], const c
static int parse_create_params(char *params, struct polydir_s *poly)
{
- char *sptr;
- struct passwd *pwd;
+ char *next;
+ struct passwd *pwd = NULL;
struct group *grp;
poly->mode = (mode_t)ULONG_MAX;
@@ -144,28 +164,40 @@ static int parse_create_params(char *params, struct polydir_s *poly)
return 0;
params++;
- params = strtok_r(params, ",", &sptr);
- if (params == NULL)
- return 0;
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
- errno = 0;
- poly->mode = (mode_t)strtoul(params, NULL, 0);
- if (errno != 0) {
- poly->mode = (mode_t)ULONG_MAX;
+ if (*params != '\0') {
+ errno = 0;
+ poly->mode = (mode_t)strtoul(params, NULL, 0);
+ if (errno != 0) {
+ poly->mode = (mode_t)ULONG_MAX;
+ }
}
- params = strtok_r(NULL, ",", &sptr);
+ params = next;
if (params == NULL)
return 0;
+ next = strchr(params, ',');
+ if (next != NULL) {
+ *next = '\0';
+ next++;
+ }
- pwd = getpwnam(params); /* session modules are not reentrant */
- if (pwd == NULL)
- return -1;
- poly->owner = pwd->pw_uid;
-
- params = strtok_r(NULL, ",", &sptr);
- if (params == NULL) {
- poly->group = pwd->pw_gid;
+ if (*params != '\0') {
+ pwd = getpwnam(params); /* session modules are not reentrant */
+ if (pwd == NULL)
+ return -1;
+ poly->owner = pwd->pw_uid;
+ }
+
+ params = next;
+ if (params == NULL || *params == '\0') {
+ if (pwd != NULL)
+ poly->group = pwd->pw_gid;
return 0;
}
grp = getgrnam(params);
@@ -199,7 +231,7 @@ static int parse_method(char *method, struct polydir_s *poly,
struct instance_data *idata)
{
enum polymethod pm;
- char *sptr;
+ char *sptr = NULL;
static const char *method_names[] = { "user", "context", "level", "tmpdir",
"tmpfs", NULL };
static const char *flag_names[] = { "create", "noinit", "iscript",
@@ -921,10 +953,158 @@ fail:
return rc;
}
+static int protect_mount(int dfd, const char *path, struct instance_data *idata)
+{
+ struct protect_dir_s *dir = idata->protect_dirs;
+ char tmpbuf[64];
+
+ while (dir != NULL) {
+ if (strcmp(path, dir->dir) == 0) {
+ return 0;
+ }
+ dir = dir->next;
+ }
+
+ dir = calloc(1, sizeof(*dir));
+
+ if (dir == NULL) {
+ return -1;
+ }
+
+ dir->dir = strdup(path);
+
+ if (dir->dir == NULL) {
+ free(dir);
+ return -1;
+ }
+
+ snprintf(tmpbuf, sizeof(tmpbuf), "/proc/self/fd/%d", dfd);
+
+ if (idata->flags & PAMNS_DEBUG) {
+ pam_syslog(idata->pamh, LOG_INFO,
+ "Protect mount of %s over itself", path);
+ }
+
+ if (mount(tmpbuf, tmpbuf, NULL, MS_BIND, NULL) != 0) {
+ int save_errno = errno;
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Protect mount of %s failed: %m", tmpbuf);
+ free(dir->dir);
+ free(dir);
+ errno = save_errno;
+ return -1;
+ }
+
+ dir->next = idata->protect_dirs;
+ idata->protect_dirs = dir;
+
+ return 0;
+}
+
+static int protect_dir(const char *path, mode_t mode, int do_mkdir,
+ struct instance_data *idata)
+{
+ char *p = strdup(path);
+ char *d;
+ char *dir = p;
+ int dfd = AT_FDCWD;
+ int dfd_next;
+ int save_errno;
+ int flags = O_RDONLY;
+ int rv = -1;
+ struct stat st;
+
+ if (p == NULL) {
+ goto error;
+ }
+
+ if (*dir == '/') {
+ dfd = open("/", flags);
+ if (dfd == -1) {
+ goto error;
+ }
+ dir++; /* assume / is safe */
+ }
+
+ while ((d=strchr(dir, '/')) != NULL) {
+ *d = '\0';
+ dfd_next = openat(dfd, dir, flags);
+ if (dfd_next == -1) {
+ goto error;
+ }
+
+ if (dfd != AT_FDCWD)
+ close(dfd);
+ dfd = dfd_next;
+
+ if (fstat(dfd, &st) != 0) {
+ goto error;
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(dfd, p, idata) == -1)
+ goto error;
+ } else if (st.st_uid != 0 || st.st_gid != 0 ||
+ (st.st_mode & S_IWOTH)) {
+ /* do not follow symlinks on subdirectories */
+ flags |= O_NOFOLLOW;
+ }
+
+ *d = '/';
+ dir = d + 1;
+ }
+
+ rv = openat(dfd, dir, flags);
+
+ if (rv == -1) {
+ if (!do_mkdir || mkdirat(dfd, dir, mode) != 0) {
+ goto error;
+ }
+ rv = openat(dfd, dir, flags);
+ }
+
+ if (rv != -1) {
+ if (fstat(rv, &st) != 0) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ goto error;
+ }
+ if (!S_ISDIR(st.st_mode)) {
+ close(rv);
+ errno = ENOTDIR;
+ rv = -1;
+ goto error;
+ }
+ }
+
+ if (flags & O_NOFOLLOW) {
+ /* we are inside user-owned dir - protect */
+ if (protect_mount(rv, p, idata) == -1) {
+ save_errno = errno;
+ close(rv);
+ rv = -1;
+ errno = save_errno;
+ }
+ }
+
+error:
+ save_errno = errno;
+ free(p);
+ if (dfd != AT_FDCWD)
+ close(dfd);
+ errno = save_errno;
+
+ return rv;
+}
+
static int check_inst_parent(char *ipath, struct instance_data *idata)
{
struct stat instpbuf;
char *inst_parent, *trailing_slash;
+ int dfd;
/*
* stat the instance parent path to make sure it exists
* and is a directory. Check that its mode is 000 (unless the
@@ -942,30 +1122,27 @@ static int check_inst_parent(char *ipath, struct instance_data *idata)
if (trailing_slash)
*trailing_slash = '\0';
- if (stat(inst_parent, &instpbuf) < 0) {
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m", inst_parent);
- free(inst_parent);
- return PAM_SESSION_ERR;
- }
+ dfd = protect_dir(inst_parent, 0, 1, idata);
- /*
- * Make sure we are dealing with a directory
- */
- if (!S_ISDIR(instpbuf.st_mode)) {
- pam_syslog(idata->pamh, LOG_ERR, "Instance parent %s is not a dir",
- inst_parent);
+ if (dfd == -1 || fstat(dfd, &instpbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error creating or accessing instance parent %s, %m", inst_parent);
+ if (dfd != -1)
+ close(dfd);
free(inst_parent);
return PAM_SESSION_ERR;
}
if ((idata->flags & PAMNS_IGN_INST_PARENT_MODE) == 0) {
- if (instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) {
- pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000",
+ if ((instpbuf.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) || instpbuf.st_uid != 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Mode of inst parent %s not 000 or owner not root",
inst_parent);
+ close(dfd);
free(inst_parent);
return PAM_SESSION_ERR;
}
}
+ close(dfd);
free(inst_parent);
return PAM_SUCCESS;
}
@@ -980,15 +1157,15 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath,
struct instance_data *idata, int newdir)
{
pid_t rc, pid;
- sighandler_t osighand = NULL;
+ struct sigaction newsa, oldsa;
int status;
const char *init_script = NAMESPACE_INIT_SCRIPT;
- osighand = signal(SIGCHLD, SIG_DFL);
- if (osighand == SIG_ERR) {
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) {
pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
- rc = PAM_SESSION_ERR;
- goto out;
+ return PAM_SESSION_ERR;
}
if ((polyptr->flags & POLYDIR_ISCRIPT) && polyptr->init_script)
@@ -1007,12 +1184,12 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath,
#ifdef WITH_SELINUX
if (idata->flags & PAMNS_SELINUX_ENABLED) {
if (setexeccon(NULL) < 0)
- exit(1);
+ _exit(1);
}
#endif
if (execl(init_script, init_script,
polyptr->dir, ipath, newdir?"1":"0", idata->user, (char *)NULL) < 0)
- exit(1);
+ _exit(1);
} else if (pid > 0) {
while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
(errno == EINTR));
@@ -1037,7 +1214,7 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath,
}
rc = PAM_SUCCESS;
out:
- (void) signal(SIGCHLD, osighand);
+ (void) sigaction(SIGCHLD, &oldsa, NULL);
return rc;
}
@@ -1051,6 +1228,8 @@ static int create_polydir(struct polydir_s *polyptr,
security_context_t dircon, oldcon = NULL;
#endif
const char *dir = polyptr->dir;
+ uid_t uid;
+ gid_t gid;
if (polyptr->mode != (mode_t)ULONG_MAX)
mode = polyptr->mode;
@@ -1077,8 +1256,8 @@ static int create_polydir(struct polydir_s *polyptr,
}
#endif
- rc = mkdir(dir, mode);
- if (rc != 0) {
+ rc = protect_dir(dir, mode, 1, idata);
+ if (rc == -1) {
pam_syslog(idata->pamh, LOG_ERR,
"Error creating directory %s: %m", dir);
return PAM_SESSION_ERR;
@@ -1098,36 +1277,41 @@ static int create_polydir(struct polydir_s *polyptr,
if (polyptr->mode != (mode_t)ULONG_MAX) {
/* explicit mode requested */
- if (chmod(dir, mode) != 0) {
+ if (fchmod(rc, mode) != 0) {
pam_syslog(idata->pamh, LOG_ERR,
"Error changing mode of directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
rmdir(dir);
return PAM_SESSION_ERR;
}
}
- if (polyptr->owner != (uid_t)ULONG_MAX) {
- if (chown(dir, polyptr->owner, polyptr->group) != 0) {
- pam_syslog(idata->pamh, LOG_ERR,
- "Unable to change owner on directory %s: %m", dir);
- rmdir(dir);
- return PAM_SESSION_ERR;
- }
- if (idata->flags & PAMNS_DEBUG)
- pam_syslog(idata->pamh, LOG_DEBUG,
- "Polydir owner %u group %u from configuration", polyptr->owner, polyptr->group);
- } else {
- if (chown(dir, idata->uid, idata->gid) != 0) {
- pam_syslog(idata->pamh, LOG_ERR,
- "Unable to change owner on directory %s: %m", dir);
- rmdir(dir);
- return PAM_SESSION_ERR;
- }
- if (idata->flags & PAMNS_DEBUG)
- pam_syslog(idata->pamh, LOG_DEBUG,
- "Polydir owner %u group %u", idata->uid, idata->gid);
+ if (polyptr->owner != (uid_t)ULONG_MAX)
+ uid = polyptr->owner;
+ else
+ uid = idata->uid;
+
+ if (polyptr->group != (gid_t)ULONG_MAX)
+ gid = polyptr->group;
+ else
+ gid = idata->gid;
+
+ if (fchown(rc, uid, gid) != 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to change owner on directory %s: %m", dir);
+ close(rc);
+ umount(dir); /* undo the eventual protection bind mount */
+ rmdir(dir);
+ return PAM_SESSION_ERR;
}
+ close(rc);
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Polydir owner %u group %u", uid, gid);
+
return PAM_SUCCESS;
}
@@ -1135,17 +1319,16 @@ static int create_polydir(struct polydir_s *polyptr,
* Create polyinstantiated instance directory (ipath).
*/
#ifdef WITH_SELINUX
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
security_context_t icontext, security_context_t ocontext,
struct instance_data *idata)
#else
-static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
+static int create_instance(struct polydir_s *polyptr, char *ipath, struct stat *statbuf,
struct instance_data *idata)
#endif
{
struct stat newstatbuf;
int fd;
- int newdir = 0;
/*
* Check to make sure instance parent is valid.
@@ -1171,7 +1354,7 @@ static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *stat
strcpy(ipath, polyptr->instance_prefix);
} else if (mkdir(ipath, S_IRUSR) < 0) {
if (errno == EEXIST)
- goto inst_init;
+ return PAM_IGNORE;
else {
pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
ipath);
@@ -1179,7 +1362,6 @@ static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *stat
}
}
- newdir = 1;
/* Open a descriptor to it to prevent races */
fd = open(ipath, O_DIRECTORY | O_RDONLY);
if (fd < 0) {
@@ -1235,33 +1417,22 @@ static int create_dirs(struct polydir_s *polyptr, char *ipath, struct stat *stat
return PAM_SESSION_ERR;
}
close(fd);
-
- /*
- * Check to see if there is a namespace initialization script in
- * the /etc/security directory. If such a script exists
- * execute it and pass directory to polyinstantiate and instance
- * directory as arguments.
- */
-
-inst_init:
- if (polyptr->flags & POLYDIR_NOINIT)
- return PAM_SUCCESS;
-
- return inst_init(polyptr, ipath, idata, newdir);
+ return PAM_SUCCESS;
}
/*
* This function performs the namespace setup for a particular directory
- * that is being polyinstantiated. It creates an MD5 hash of instance
- * directory, calls create_dirs to create it with appropriate
+ * that is being polyinstantiated. It calls poly_name to create name of instance
+ * directory, calls create_instance to mkdir it with appropriate
* security attributes, and performs bind mount to setup the process
* namespace.
*/
static int ns_setup(struct polydir_s *polyptr,
struct instance_data *idata)
{
- int retval = 0;
+ int retval;
+ int newdir = 1;
char *inst_dir = NULL;
char *instname = NULL;
struct stat statbuf;
@@ -1273,37 +1444,40 @@ static int ns_setup(struct polydir_s *polyptr,
pam_syslog(idata->pamh, LOG_DEBUG,
"Set namespace for directory %s", polyptr->dir);
- while (stat(polyptr->dir, &statbuf) < 0) {
- if (retval || !(polyptr->flags & POLYDIR_CREATE)) {
- pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
- polyptr->dir);
- return PAM_SESSION_ERR;
- } else {
- if (create_polydir(polyptr, idata) != PAM_SUCCESS)
- return PAM_SESSION_ERR;
- retval = PAM_SESSION_ERR; /* bail out on next failed stat */
- }
- }
+ retval = protect_dir(polyptr->dir, 0, 0, idata);
- /*
- * Make sure we are dealing with a directory
- */
- if (!S_ISDIR(statbuf.st_mode)) {
- pam_syslog(idata->pamh, LOG_ERR, "Polydir %s is not a dir",
+ if (retval < 0 && errno != ENOENT) {
+ pam_syslog(idata->pamh, LOG_ERR, "Polydir %s access error: %m",
polyptr->dir);
- return PAM_SESSION_ERR;
+ return PAM_SESSION_ERR;
}
+ if (retval < 0 && (polyptr->flags & POLYDIR_CREATE)) {
+ if (create_polydir(polyptr, idata) != PAM_SUCCESS)
+ return PAM_SESSION_ERR;
+ } else {
+ close(retval);
+ }
+
if (polyptr->method == TMPFS) {
if (mount("tmpfs", polyptr->dir, "tmpfs", 0, NULL) < 0) {
pam_syslog(idata->pamh, LOG_ERR, "Error mounting tmpfs on %s, %m",
polyptr->dir);
return PAM_SESSION_ERR;
}
- /* we must call inst_init after the mount in this case */
+
+ if (polyptr->flags & POLYDIR_NOINIT)
+ return PAM_SUCCESS;
+
return inst_init(polyptr, "tmpfs", idata, 1);
}
+ if (stat(polyptr->dir, &statbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s: %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
/*
* Obtain the name of instance pathname based on the
* polyinstantiation method and instance context returned by
@@ -1341,14 +1515,18 @@ static int ns_setup(struct polydir_s *polyptr,
* contexts, owner, group and mode bits.
*/
#ifdef WITH_SELINUX
- retval = create_dirs(polyptr, inst_dir, &statbuf, instcontext,
+ retval = create_instance(polyptr, inst_dir, &statbuf, instcontext,
origcontext, idata);
#else
- retval = create_dirs(polyptr, inst_dir, &statbuf, idata);
+ retval = create_instance(polyptr, inst_dir, &statbuf, idata);
#endif
- if (retval < 0) {
- pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir");
+ if (retval == PAM_IGNORE) {
+ newdir = 0;
+ retval = PAM_SUCCESS;
+ }
+
+ if (retval != PAM_SUCCESS) {
goto error_out;
}
@@ -1363,6 +1541,9 @@ static int ns_setup(struct polydir_s *polyptr,
goto error_out;
}
+ if (!(polyptr->flags & POLYDIR_NOINIT))
+ retval = inst_init(polyptr, inst_dir, idata, newdir);
+
goto cleanup;
/*
@@ -1413,14 +1594,14 @@ static int cleanup_tmpdirs(struct instance_data *idata)
{
struct polydir_s *pptr;
pid_t rc, pid;
- sighandler_t osighand = NULL;
+ struct sigaction newsa, oldsa;
int status;
- osighand = signal(SIGCHLD, SIG_DFL);
- if (osighand == SIG_ERR) {
+ memset(&newsa, '\0', sizeof(newsa));
+ newsa.sa_handler = SIG_DFL;
+ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) {
pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
- rc = PAM_SESSION_ERR;
- goto out;
+ return PAM_SESSION_ERR;
}
for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
@@ -1430,16 +1611,16 @@ static int cleanup_tmpdirs(struct instance_data *idata)
#ifdef WITH_SELINUX
if (idata->flags & PAMNS_SELINUX_ENABLED) {
if (setexeccon(NULL) < 0)
- exit(1);
+ _exit(1);
}
#endif
if (execl("/bin/rm", "/bin/rm", "-rf", pptr->instance_prefix, (char *)NULL) < 0)
- exit(1);
+ _exit(1);
} else if (pid > 0) {
while (((rc = waitpid(pid, &status, 0)) == (pid_t)-1) &&
(errno == EINTR));
if (rc == (pid_t)-1) {
- pam_syslog(idata->pamh, LOG_ERR, "waitpid failed- %m");
+ pam_syslog(idata->pamh, LOG_ERR, "waitpid failed: %m");
rc = PAM_SESSION_ERR;
goto out;
}
@@ -1458,7 +1639,7 @@ static int cleanup_tmpdirs(struct instance_data *idata)
rc = PAM_SUCCESS;
out:
- signal(SIGCHLD, osighand);
+ sigaction(SIGCHLD, &oldsa, NULL);
return rc;
}
@@ -1600,12 +1781,21 @@ static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt)
}
}
out:
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
cleanup_tmpdirs(idata);
- else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
- cleanup_data) != PAM_SUCCESS) {
- pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace data");
+ unprotect_dirs(idata->protect_dirs);
+ } else if (pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, idata->protect_dirs,
+ cleanup_protect_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace protect data");
+ cleanup_tmpdirs(idata);
+ unprotect_dirs(idata->protect_dirs);
+ return PAM_SYSTEM_ERR;
+ } else if (pam_set_data(idata->pamh, NAMESPACE_POLYDIR_DATA, idata->polydirs_ptr,
+ cleanup_polydir_data) != PAM_SUCCESS) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to set namespace polydir data");
cleanup_tmpdirs(idata);
+ pam_set_data(idata->pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
+ idata->protect_dirs = NULL;
return PAM_SYSTEM_ERR;
}
return retval;
@@ -1742,6 +1932,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
/* init instance data */
idata.flags = 0;
idata.polydirs_ptr = NULL;
+ idata.protect_dirs = NULL;
idata.pamh = pamh;
#ifdef WITH_SELINUX
if (is_selinux_enabled())
@@ -1893,6 +2084,7 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
}
pam_set_data(idata.pamh, NAMESPACE_POLYDIR_DATA, NULL, NULL);
+ pam_set_data(idata.pamh, NAMESPACE_PROTECT_DATA, NULL, NULL);
return PAM_SUCCESS;
}
diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h
index bfc0da17..da21bd70 100644
--- a/modules/pam_namespace/pam_namespace.h
+++ b/modules/pam_namespace/pam_namespace.h
@@ -107,6 +107,7 @@
#define NAMESPACE_MAX_DIR_LEN 80
#define NAMESPACE_POLYDIR_DATA "pam_namespace:polydir_data"
+#define NAMESPACE_PROTECT_DATA "pam_namespace:protect_data"
/*
* Polyinstantiation method options, based on user, security context
@@ -156,9 +157,15 @@ struct polydir_s {
struct polydir_s *next; /* pointer to the next polydir entry */
};
+struct protect_dir_s {
+ char *dir; /* protected directory */
+ struct protect_dir_s *next; /* next entry */
+};
+
struct instance_data {
pam_handle_t *pamh; /* The pam handle for this instance */
struct polydir_s *polydirs_ptr; /* The linked list pointer */
+ struct protect_dir_s *protect_dirs; /* The pointer to stack of mount-protected dirs */
char user[LOGIN_NAME_MAX]; /* User name */
char ruser[LOGIN_NAME_MAX]; /* Requesting user name */
uid_t uid; /* The uid of the user */
@@ -166,3 +173,4 @@ struct instance_data {
uid_t ruid; /* The uid of the requesting user */
unsigned long flags; /* Flags for debug, selinux etc */
};
+