summaryrefslogtreecommitdiff
path: root/Linux-PAM/modules/pam_namespace
diff options
context:
space:
mode:
Diffstat (limited to 'Linux-PAM/modules/pam_namespace')
-rw-r--r--Linux-PAM/modules/pam_namespace/Makefile.am39
-rw-r--r--Linux-PAM/modules/pam_namespace/Makefile.in772
-rw-r--r--Linux-PAM/modules/pam_namespace/README129
-rw-r--r--Linux-PAM/modules/pam_namespace/README.xml139
-rw-r--r--Linux-PAM/modules/pam_namespace/md5.c260
-rw-r--r--Linux-PAM/modules/pam_namespace/md5.h28
-rw-r--r--Linux-PAM/modules/pam_namespace/namespace.conf30
-rw-r--r--Linux-PAM/modules/pam_namespace/namespace.conf.596
-rw-r--r--Linux-PAM/modules/pam_namespace/namespace.conf.5.xml151
-rwxr-xr-xLinux-PAM/modules/pam_namespace/namespace.init24
-rw-r--r--Linux-PAM/modules/pam_namespace/pam_namespace.8110
-rw-r--r--Linux-PAM/modules/pam_namespace/pam_namespace.8.xml317
-rw-r--r--Linux-PAM/modules/pam_namespace/pam_namespace.c1337
-rw-r--r--Linux-PAM/modules/pam_namespace/pam_namespace.h135
-rwxr-xr-xLinux-PAM/modules/pam_namespace/tst-pam_namespace2
15 files changed, 3569 insertions, 0 deletions
diff --git a/Linux-PAM/modules/pam_namespace/Makefile.am b/Linux-PAM/modules/pam_namespace/Makefile.am
new file mode 100644
index 00000000..bbcb2f70
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/Makefile.am
@@ -0,0 +1,39 @@
+#
+# Copyright (c) 2006 Red Hat, Inc.
+#
+
+CLEANFILES = *~
+MAN5 = namespace.conf.5
+MAN8 = pam_namespace.8
+
+XMLS = README.xml namespace.conf.5.xml pam_namespace.8.xml
+
+if ENABLE_REGENERATE_MAN
+noinst_DATA = README
+-include $(top_srcdir)/Make.xml.rules
+endif
+
+EXTRA_DIST = README namespace.conf namespace.init $(MAN5) $(MAN8) $(XMLS) tst-pam_namespace
+
+noinst_HEADERS = md5.h
+
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_NAMESPACE_CONFIG=\"$(SCONFIGDIR)/namespace.conf\"
+AM_LDFLAGS = -no-undefined -avoid-version -module \
+ -L$(top_builddir)/libpam -lpam @LIBSELINUX@
+if HAVE_VERSIONING
+ AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map
+endif
+
+if HAVE_UNSHARE
+securelib_LTLIBRARIES = pam_namespace.la
+pam_namespace_la_SOURCES = pam_namespace.c pam_namespace.h md5.c md5.h
+
+secureconf_DATA = namespace.conf
+secureconf_SCRIPTS = namespace.init
+TESTS = tst-pam_namespace
+man_MANS = $(MAN5) $(MAN8)
+endif
diff --git a/Linux-PAM/modules/pam_namespace/Makefile.in b/Linux-PAM/modules/pam_namespace/Makefile.in
new file mode 100644
index 00000000..8beee4ce
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/Makefile.in
@@ -0,0 +1,772 @@
+# Makefile.in generated by automake 1.10 from Makefile.am.
+# @configure_input@
+
+# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+# 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+# This Makefile.in is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
+# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
+# PARTICULAR PURPOSE.
+
+@SET_MAKE@
+
+#
+# Copyright (c) 2006 Red Hat, Inc.
+#
+
+
+
+
+VPATH = @srcdir@
+pkgdatadir = $(datadir)/@PACKAGE@
+pkglibdir = $(libdir)/@PACKAGE@
+pkgincludedir = $(includedir)/@PACKAGE@
+am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
+install_sh_DATA = $(install_sh) -c -m 644
+install_sh_PROGRAM = $(install_sh) -c
+install_sh_SCRIPT = $(install_sh) -c
+INSTALL_HEADER = $(INSTALL_DATA)
+transform = $(program_transform_name)
+NORMAL_INSTALL = :
+PRE_INSTALL = :
+POST_INSTALL = :
+NORMAL_UNINSTALL = :
+PRE_UNINSTALL = :
+POST_UNINSTALL = :
+build_triplet = @build@
+host_triplet = @host@
+@HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map
+subdir = modules/pam_namespace
+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/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)/configure.in
+am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
+ $(ACLOCAL_M4)
+mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
+CONFIG_HEADER = $(top_builddir)/config.h
+CONFIG_CLEAN_FILES =
+am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
+am__vpath_adj = case $$p in \
+ $(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
+ *) f=$$p;; \
+ esac;
+am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
+am__installdirs = "$(DESTDIR)$(securelibdir)" \
+ "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(man5dir)" \
+ "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"
+securelibLTLIBRARIES_INSTALL = $(INSTALL)
+LTLIBRARIES = $(securelib_LTLIBRARIES)
+pam_namespace_la_LIBADD =
+am__pam_namespace_la_SOURCES_DIST = pam_namespace.c pam_namespace.h \
+ md5.c md5.h
+@HAVE_UNSHARE_TRUE@am_pam_namespace_la_OBJECTS = pam_namespace.lo \
+@HAVE_UNSHARE_TRUE@ md5.lo
+pam_namespace_la_OBJECTS = $(am_pam_namespace_la_OBJECTS)
+@HAVE_UNSHARE_TRUE@am_pam_namespace_la_rpath = -rpath $(securelibdir)
+secureconfSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+SCRIPTS = $(secureconf_SCRIPTS)
+DEFAULT_INCLUDES = -I. -I$(top_builddir)@am__isrc@
+depcomp = $(SHELL) $(top_srcdir)/depcomp
+am__depfiles_maybe = depfiles
+COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
+ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
+ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
+CCLD = $(CC)
+LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
+ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
+ $(LDFLAGS) -o $@
+SOURCES = $(pam_namespace_la_SOURCES)
+DIST_SOURCES = $(am__pam_namespace_la_SOURCES_DIST)
+man5dir = $(mandir)/man5
+man8dir = $(mandir)/man8
+NROFF = nroff
+MANS = $(man_MANS)
+secureconfDATA_INSTALL = $(INSTALL_DATA)
+DATA = $(noinst_DATA) $(secureconf_DATA)
+HEADERS = $(noinst_HEADERS)
+ETAGS = etags
+CTAGS = ctags
+DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
+ACLOCAL = @ACLOCAL@
+AMTAR = @AMTAR@
+AR = @AR@
+AUTOCONF = @AUTOCONF@
+AUTOHEADER = @AUTOHEADER@
+AUTOMAKE = @AUTOMAKE@
+AWK = @AWK@
+BROWSER = @BROWSER@
+CC = @CC@
+CCDEPMODE = @CCDEPMODE@
+CFLAGS = @CFLAGS@
+CPP = @CPP@
+CPPFLAGS = @CPPFLAGS@
+CXX = @CXX@
+CXXCPP = @CXXCPP@
+CXXDEPMODE = @CXXDEPMODE@
+CXXFLAGS = @CXXFLAGS@
+CYGPATH_W = @CYGPATH_W@
+DEFS = @DEFS@
+DEPDIR = @DEPDIR@
+ECHO = @ECHO@
+ECHO_C = @ECHO_C@
+ECHO_N = @ECHO_N@
+ECHO_T = @ECHO_T@
+EGREP = @EGREP@
+EXEEXT = @EXEEXT@
+F77 = @F77@
+FFLAGS = @FFLAGS@
+FO2PDF = @FO2PDF@
+GMSGFMT = @GMSGFMT@
+GMSGFMT_015 = @GMSGFMT_015@
+GREP = @GREP@
+HAVE_KEY_MANAGEMENT = @HAVE_KEY_MANAGEMENT@
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+INSTALL_PROGRAM = @INSTALL_PROGRAM@
+INSTALL_SCRIPT = @INSTALL_SCRIPT@
+INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INTLLIBS = @INTLLIBS@
+INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@
+LDFLAGS = @LDFLAGS@
+LEX = @LEX@
+LEXLIB = @LEXLIB@
+LEX_OUTPUT_ROOT = @LEX_OUTPUT_ROOT@
+LIBAUDIT = @LIBAUDIT@
+LIBCRACK = @LIBCRACK@
+LIBCRYPT = @LIBCRYPT@
+LIBDB = @LIBDB@
+LIBDL = @LIBDL@
+LIBICONV = @LIBICONV@
+LIBINTL = @LIBINTL@
+LIBNSL = @LIBNSL@
+LIBOBJS = @LIBOBJS@
+LIBPRELUDE_CFLAGS = @LIBPRELUDE_CFLAGS@
+LIBPRELUDE_CONFIG = @LIBPRELUDE_CONFIG@
+LIBPRELUDE_CONFIG_PREFIX = @LIBPRELUDE_CONFIG_PREFIX@
+LIBPRELUDE_LDFLAGS = @LIBPRELUDE_LDFLAGS@
+LIBPRELUDE_LIBS = @LIBPRELUDE_LIBS@
+LIBPRELUDE_PREFIX = @LIBPRELUDE_PREFIX@
+LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@
+LIBS = @LIBS@
+LIBSELINUX = @LIBSELINUX@
+LIBTOOL = @LIBTOOL@
+LN_S = @LN_S@
+LTLIBICONV = @LTLIBICONV@
+LTLIBINTL = @LTLIBINTL@
+LTLIBOBJS = @LTLIBOBJS@
+MAKEINFO = @MAKEINFO@
+MKDIR_P = @MKDIR_P@
+MSGFMT = @MSGFMT@
+MSGFMT_015 = @MSGFMT_015@
+MSGMERGE = @MSGMERGE@
+OBJEXT = @OBJEXT@
+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@
+POSUB = @POSUB@
+RANLIB = @RANLIB@
+SCONFIGDIR = @SCONFIGDIR@
+SECUREDIR = @SECUREDIR@
+SET_MAKE = @SET_MAKE@
+SHELL = @SHELL@
+STRIP = @STRIP@
+USE_NLS = @USE_NLS@
+VERSION = @VERSION@
+WITH_DEBUG = @WITH_DEBUG@
+WITH_PAMLOCKING = @WITH_PAMLOCKING@
+XGETTEXT = @XGETTEXT@
+XGETTEXT_015 = @XGETTEXT_015@
+XMLCATALOG = @XMLCATALOG@
+XMLLINT = @XMLLINT@
+XML_CATALOG_FILE = @XML_CATALOG_FILE@
+XSLTPROC = @XSLTPROC@
+YACC = @YACC@
+YFLAGS = @YFLAGS@
+abs_builddir = @abs_builddir@
+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@
+am__include = @am__include@
+am__leading_dot = @am__leading_dot@
+am__quote = @am__quote@
+am__tar = @am__tar@
+am__untar = @am__untar@
+bindir = @bindir@
+build = @build@
+build_alias = @build_alias@
+build_cpu = @build_cpu@
+build_os = @build_os@
+build_vendor = @build_vendor@
+builddir = @builddir@
+datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
+exec_prefix = @exec_prefix@
+host = @host@
+host_alias = @host_alias@
+host_cpu = @host_cpu@
+host_os = @host_os@
+host_vendor = @host_vendor@
+htmldir = @htmldir@
+includedir = @includedir@
+infodir = @infodir@
+install_sh = @install_sh@
+libc_cv_fpie = @libc_cv_fpie@
+libdir = @libdir@
+libexecdir = @libexecdir@
+localedir = @localedir@
+localstatedir = @localstatedir@
+mandir = @mandir@
+mkdir_p = @mkdir_p@
+oldincludedir = @oldincludedir@
+pam_cv_ld_as_needed = @pam_cv_ld_as_needed@
+pam_xauth_path = @pam_xauth_path@
+pdfdir = @pdfdir@
+prefix = @prefix@
+program_transform_name = @program_transform_name@
+psdir = @psdir@
+sbindir = @sbindir@
+sharedstatedir = @sharedstatedir@
+srcdir = @srcdir@
+sysconfdir = @sysconfdir@
+target_alias = @target_alias@
+top_builddir = @top_builddir@
+top_srcdir = @top_srcdir@
+CLEANFILES = *~
+MAN5 = namespace.conf.5
+MAN8 = pam_namespace.8
+XMLS = README.xml namespace.conf.5.xml pam_namespace.8.xml
+@ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README
+EXTRA_DIST = README namespace.conf namespace.init $(MAN5) $(MAN8) $(XMLS) tst-pam_namespace
+noinst_HEADERS = md5.h
+securelibdir = $(SECUREDIR)
+secureconfdir = $(SCONFIGDIR)
+AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \
+ -DPAM_NAMESPACE_CONFIG=\"$(SCONFIGDIR)/namespace.conf\"
+
+AM_LDFLAGS = -no-undefined -avoid-version -module \
+ -L$(top_builddir)/libpam -lpam @LIBSELINUX@ $(am__append_1)
+@HAVE_UNSHARE_TRUE@securelib_LTLIBRARIES = pam_namespace.la
+@HAVE_UNSHARE_TRUE@pam_namespace_la_SOURCES = pam_namespace.c pam_namespace.h md5.c md5.h
+@HAVE_UNSHARE_TRUE@secureconf_DATA = namespace.conf
+@HAVE_UNSHARE_TRUE@secureconf_SCRIPTS = namespace.init
+@HAVE_UNSHARE_TRUE@TESTS = tst-pam_namespace
+@HAVE_UNSHARE_TRUE@man_MANS = $(MAN5) $(MAN8)
+all: all-am
+
+.SUFFIXES:
+.SUFFIXES: .c .lo .o .obj
+$(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; \
+ exit 1;; \
+ esac; \
+ done; \
+ echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu modules/pam_namespace/Makefile'; \
+ cd $(top_srcdir) && \
+ $(AUTOMAKE) --gnu modules/pam_namespace/Makefile
+.PRECIOUS: Makefile
+Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
+ @case '$?' in \
+ *config.status*) \
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
+ *) \
+ echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
+ cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
+ esac;
+
+$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+
+$(top_srcdir)/configure: $(am__configure_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+$(ACLOCAL_M4): $(am__aclocal_m4_deps)
+ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
+install-securelibLTLIBRARIES: $(securelib_LTLIBRARIES)
+ @$(NORMAL_INSTALL)
+ test -z "$(securelibdir)" || $(MKDIR_P) "$(DESTDIR)$(securelibdir)"
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ if test -f $$p; then \
+ f=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) '$$p' '$(DESTDIR)$(securelibdir)/$$f'"; \
+ $(LIBTOOL) --mode=install $(securelibLTLIBRARIES_INSTALL) $(INSTALL_STRIP_FLAG) "$$p" "$(DESTDIR)$(securelibdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-securelibLTLIBRARIES:
+ @$(NORMAL_UNINSTALL)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ p=$(am__strip_dir) \
+ echo " $(LIBTOOL) --mode=uninstall rm -f '$(DESTDIR)$(securelibdir)/$$p'"; \
+ $(LIBTOOL) --mode=uninstall rm -f "$(DESTDIR)$(securelibdir)/$$p"; \
+ done
+
+clean-securelibLTLIBRARIES:
+ -test -z "$(securelib_LTLIBRARIES)" || rm -f $(securelib_LTLIBRARIES)
+ @list='$(securelib_LTLIBRARIES)'; for p in $$list; do \
+ dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
+ test "$$dir" != "$$p" || dir=.; \
+ echo "rm -f \"$${dir}/so_locations\""; \
+ rm -f "$${dir}/so_locations"; \
+ done
+pam_namespace.la: $(pam_namespace_la_OBJECTS) $(pam_namespace_la_DEPENDENCIES)
+ $(LINK) $(am_pam_namespace_la_rpath) $(pam_namespace_la_OBJECTS) $(pam_namespace_la_LIBADD) $(LIBS)
+install-secureconfSCRIPTS: $(secureconf_SCRIPTS)
+ @$(NORMAL_INSTALL)
+ test -z "$(secureconfdir)" || $(MKDIR_P) "$(DESTDIR)$(secureconfdir)"
+ @list='$(secureconf_SCRIPTS)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ if test -f $$d$$p; then \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " $(secureconfSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ $(secureconfSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(secureconfdir)/$$f"; \
+ else :; fi; \
+ done
+
+uninstall-secureconfSCRIPTS:
+ @$(NORMAL_UNINSTALL)
+ @list='$(secureconf_SCRIPTS)'; for p in $$list; do \
+ f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+ echo " rm -f '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(secureconfdir)/$$f"; \
+ done
+
+mostlyclean-compile:
+ -rm -f *.$(OBJEXT)
+
+distclean-compile:
+ -rm -f *.tab.c
+
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/md5.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_namespace.Plo@am__quote@
+
+.c.o:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c $<
+
+.c.obj:
+@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
+
+.c.lo:
+@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
+@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
+
+mostlyclean-libtool:
+ -rm -f *.lo
+
+clean-libtool:
+ -rm -rf .libs _libs
+install-man5: $(man5_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man5dir)" || $(MKDIR_P) "$(DESTDIR)$(man5dir)"
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man5dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+uninstall-man5:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man5_MANS) $(dist_man5_MANS) $(nodist_man5_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.5*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 5*) ;; \
+ *) ext='5' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man5dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man5dir)/$$inst"; \
+ done
+install-man8: $(man8_MANS) $(man_MANS)
+ @$(NORMAL_INSTALL)
+ test -z "$(man8dir)" || $(MKDIR_P) "$(DESTDIR)$(man8dir)"
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \
+ else file=$$i; fi; \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man8dir)/$$inst'"; \
+ $(INSTALL_DATA) "$$file" "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+uninstall-man8:
+ @$(NORMAL_UNINSTALL)
+ @list='$(man8_MANS) $(dist_man8_MANS) $(nodist_man8_MANS)'; \
+ l2='$(man_MANS) $(dist_man_MANS) $(nodist_man_MANS)'; \
+ for i in $$l2; do \
+ case "$$i" in \
+ *.8*) list="$$list $$i" ;; \
+ esac; \
+ done; \
+ for i in $$list; do \
+ ext=`echo $$i | sed -e 's/^.*\\.//'`; \
+ case "$$ext" in \
+ 8*) ;; \
+ *) ext='8' ;; \
+ esac; \
+ inst=`echo $$i | sed -e 's/\\.[0-9a-z]*$$//'`; \
+ inst=`echo $$inst | sed -e 's/^.*\///'`; \
+ inst=`echo $$inst | sed '$(transform)'`.$$ext; \
+ echo " rm -f '$(DESTDIR)$(man8dir)/$$inst'"; \
+ rm -f "$(DESTDIR)$(man8dir)/$$inst"; \
+ done
+install-secureconfDATA: $(secureconf_DATA)
+ @$(NORMAL_INSTALL)
+ test -z "$(secureconfdir)" || $(MKDIR_P) "$(DESTDIR)$(secureconfdir)"
+ @list='$(secureconf_DATA)'; for p in $$list; do \
+ if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+ f=$(am__strip_dir) \
+ echo " $(secureconfDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ $(secureconfDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(secureconfdir)/$$f"; \
+ done
+
+uninstall-secureconfDATA:
+ @$(NORMAL_UNINSTALL)
+ @list='$(secureconf_DATA)'; for p in $$list; do \
+ f=$(am__strip_dir) \
+ echo " rm -f '$(DESTDIR)$(secureconfdir)/$$f'"; \
+ rm -f "$(DESTDIR)$(secureconfdir)/$$f"; \
+ done
+
+ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
+ list='$(SOURCES) $(HEADERS) $(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; } \
+ END { for (i in files) print i; }'`; \
+ mkid -fID $$unique
+tags: TAGS
+
+TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; } \
+ END { for (i in files) print i; }'`; \
+ if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \
+ test -n "$$unique" || unique=$$empty_fix; \
+ $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
+ $$tags $$unique; \
+ fi
+ctags: CTAGS
+CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \
+ $(TAGS_FILES) $(LISP)
+ tags=; \
+ here=`pwd`; \
+ list='$(SOURCES) $(HEADERS) $(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; } \
+ END { for (i in files) print i; }'`; \
+ test -z "$(CTAGS_ARGS)$$tags$$unique" \
+ || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
+ $$tags $$unique
+
+GTAGS:
+ here=`$(am__cd) $(top_builddir) && pwd` \
+ && cd $(top_srcdir) \
+ && gtags -i $(GTAGS_ARGS) $$here
+
+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='[ ]'; \
+ srcdir=$(srcdir); export srcdir; \
+ list=' $(TESTS) '; \
+ if test -n "$$list"; then \
+ for tst in $$list; do \
+ if test -f ./$$tst; then dir=./; \
+ elif test -f $$tst; then dir=; \
+ else dir="$(srcdir)/"; fi; \
+ if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xpass=`expr $$xpass + 1`; \
+ failed=`expr $$failed + 1`; \
+ echo "XPASS: $$tst"; \
+ ;; \
+ *) \
+ echo "PASS: $$tst"; \
+ ;; \
+ esac; \
+ elif test $$? -ne 77; then \
+ all=`expr $$all + 1`; \
+ case " $(XFAIL_TESTS) " in \
+ *$$ws$$tst$$ws*) \
+ xfail=`expr $$xfail + 1`; \
+ echo "XFAIL: $$tst"; \
+ ;; \
+ *) \
+ failed=`expr $$failed + 1`; \
+ echo "FAIL: $$tst"; \
+ ;; \
+ esac; \
+ else \
+ skip=`expr $$skip + 1`; \
+ echo "SKIP: $$tst"; \
+ fi; \
+ done; \
+ if test "$$failed" -eq 0; then \
+ if test "$$xfail" -eq 0; then \
+ banner="All $$all tests passed"; \
+ else \
+ banner="All $$all tests behaved as expected ($$xfail expected failures)"; \
+ fi; \
+ else \
+ if test "$$xpass" -eq 0; then \
+ banner="$$failed of $$all tests failed"; \
+ else \
+ 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)"; \
+ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$skipped"; \
+ fi; \
+ report=""; \
+ if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \
+ report="Please report to $(PACKAGE_BUGREPORT)"; \
+ test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \
+ dashes="$$report"; \
+ fi; \
+ dashes=`echo "$$dashes" | sed s/./=/g`; \
+ echo "$$dashes"; \
+ echo "$$banner"; \
+ test -z "$$skipped" || echo "$$skipped"; \
+ test -z "$$report" || echo "$$report"; \
+ echo "$$dashes"; \
+ test "$$failed" -eq 0; \
+ else :; fi
+
+distdir: $(DISTFILES)
+ @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
+ list='$(DISTFILES)'; \
+ dist_files=`for file in $$list; do echo $$file; done | \
+ sed -e "s|^$$srcdirstrip/||;t" \
+ -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
+ case $$dist_files in \
+ */*) $(MKDIR_P) `echo "$$dist_files" | \
+ sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
+ sort -u` ;; \
+ esac; \
+ for file in $$dist_files; do \
+ if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
+ if test -d $$d/$$file; then \
+ dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
+ if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
+ cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \
+ fi; \
+ cp -pR $$d/$$file $(distdir)$$dir || exit 1; \
+ else \
+ test -f $(distdir)/$$file \
+ || cp -p $$d/$$file $(distdir)/$$file \
+ || exit 1; \
+ fi; \
+ done
+check-am: all-am
+ $(MAKE) $(AM_MAKEFLAGS) check-TESTS
+check: check-am
+all-am: Makefile $(LTLIBRARIES) $(SCRIPTS) $(MANS) $(DATA) $(HEADERS)
+installdirs:
+ for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(secureconfdir)" "$(DESTDIR)$(man5dir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(secureconfdir)"; do \
+ test -z "$$dir" || $(MKDIR_P) "$$dir"; \
+ done
+install: install-am
+install-exec: install-exec-am
+install-data: install-data-am
+uninstall: uninstall-am
+
+install-am: all-am
+ @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
+
+installcheck: installcheck-am
+install-strip:
+ $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
+ install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
+ `test -z '$(STRIP)' || \
+ echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
+mostlyclean-generic:
+
+clean-generic:
+ -test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
+
+distclean-generic:
+ -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
+
+maintainer-clean-generic:
+ @echo "This command is intended for maintainers to use"
+ @echo "it deletes files that may require special tools to rebuild."
+clean: clean-am
+
+clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \
+ mostlyclean-am
+
+distclean: distclean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+distclean-am: clean-am distclean-compile distclean-generic \
+ distclean-tags
+
+dvi: dvi-am
+
+dvi-am:
+
+html: html-am
+
+info: info-am
+
+info-am:
+
+install-data-am: install-man install-secureconfDATA \
+ install-secureconfSCRIPTS install-securelibLTLIBRARIES
+
+install-dvi: install-dvi-am
+
+install-exec-am:
+
+install-html: install-html-am
+
+install-info: install-info-am
+
+install-man: install-man5 install-man8
+
+install-pdf: install-pdf-am
+
+install-ps: install-ps-am
+
+installcheck-am:
+
+maintainer-clean: maintainer-clean-am
+ -rm -rf ./$(DEPDIR)
+ -rm -f Makefile
+maintainer-clean-am: distclean-am maintainer-clean-generic
+
+mostlyclean: mostlyclean-am
+
+mostlyclean-am: mostlyclean-compile mostlyclean-generic \
+ mostlyclean-libtool
+
+pdf: pdf-am
+
+pdf-am:
+
+ps: ps-am
+
+ps-am:
+
+uninstall-am: uninstall-man uninstall-secureconfDATA \
+ uninstall-secureconfSCRIPTS uninstall-securelibLTLIBRARIES
+
+uninstall-man: uninstall-man5 uninstall-man8
+
+.MAKE: install-am install-strip
+
+.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \
+ clean-generic clean-libtool clean-securelibLTLIBRARIES ctags \
+ distclean distclean-compile distclean-generic \
+ distclean-libtool distclean-tags distdir dvi dvi-am html \
+ html-am info info-am install install-am install-data \
+ install-data-am install-dvi install-dvi-am install-exec \
+ install-exec-am install-html install-html-am install-info \
+ install-info-am install-man install-man5 install-man8 \
+ install-pdf install-pdf-am install-ps install-ps-am \
+ install-secureconfDATA install-secureconfSCRIPTS \
+ install-securelibLTLIBRARIES install-strip installcheck \
+ installcheck-am installdirs maintainer-clean \
+ maintainer-clean-generic mostlyclean mostlyclean-compile \
+ mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
+ tags uninstall uninstall-am uninstall-man uninstall-man5 \
+ uninstall-man8 uninstall-secureconfDATA \
+ uninstall-secureconfSCRIPTS uninstall-securelibLTLIBRARIES
+
+@ENABLE_REGENERATE_MAN_TRUE@-include $(top_srcdir)/Make.xml.rules
+# Tell versions [3.59,3.63) of GNU make to not export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/Linux-PAM/modules/pam_namespace/README b/Linux-PAM/modules/pam_namespace/README
new file mode 100644
index 00000000..c47ba232
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/README
@@ -0,0 +1,129 @@
+pam_namespace — PAM module for configuring namespace for a session
+
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+
+
+pam_namespace module:
+Setup a private namespace with polyinstantiated directories.
+
+THEORY OF OPERATION:
+The pam namespace module consults /etc/security/namespace.conf
+configuration file and sets up a private namespace with polyinstantiated
+directories for a session managed by PAM. A skeleton namespace.conf
+installed by default provides example for polyinstantiating /tmp, /var/tmp
+and users' home directory.
+
+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.
+
+Each line in namespace.conf describes a limit for a user in the form:
+
+<polydir> <instance_prefix> <method> <list_of_uids>
+
+Where:
+<polydir> - is the absolute pathname of the directory to polyinstantiate
+ Special entry $HOME is supported to designate user's home directory.
+ This field cannot be blank.
+
+<instance_prefix> - is the string prefix used to build the pathname for the
+ instantiation of <polydir>. The directory security context, or
+ optionally its md5sum string (32 hex characters), is appended to
+ the prefix 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 $HOME is replaced with
+ the user's home directory, and $USER with the username.
+ This field cannot be blank.
+
+<method> - is the method used for polyinstantiation. It can take 3 different
+ values; "user" for polyinstantiation based on user name, "context"
+ for polyinstantiation based on process security context, and "both"
+ for polyinstantiation based on both user name and security context.
+ Methods "context" and "both" are only available with SELinux. This
+ field cannot be blank.
+
+<list_of_uids> - 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.
+
+EXAMPLE /etc/security/namespace.conf configuration file:
+=======================================================
+# Following three lines will polyinstantiate /tmp, /var/tmp and user's home
+# directories. /tmp and /var/tmp will be polyinstantiated based on both
+# security context as well as user name, whereas home directory will
+# be polyinstantiated based on security context only. 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. The user name and/or context is appended to the instance prefix.
+#
+# Note that instance directories do not have to reside inside 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.
+#
+# Instance parent directories must exist for the polyinstantiation
+# mechanism to work. By default, they should be created with the mode
+# of 000. pam_namespace module will enforce this mode unless it
+# is explicitly called with an argument to ignore the mode of the
+# instance parent. System administrators should use this argument with
+# caution, as it will reduce security and isolation achieved by
+# polyinstantiation.
+#
+/tmp /tmp-inst/ both root,adm
+/var/tmp /var/tmp/tmp-inst/ both root,adm
+$HOME $HOME/$USER.inst/inst- context
+
+ARGUMENTS RECOGNIZED:
+ debug
+ Verbose logging by syslog
+
+ unmnt_remnt
+ 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.
+
+ unmnt_only
+ For trusted programs that want to undo any existing bind mounts
+ and process instance directories on their own, this argument
+ allows them to unmount currently mounted instance directories.
+
+ require_selinux
+ If selinux is not enabled, return failure.
+
+ gen_hash
+ Instead of using the security context string for the instance
+ name, generate and use its md5 hash.
+
+ ignore_config_error
+ 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.
+
+ ignore_instance_parent_mode
+ 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.
+
+MODULE SERVICES PROVIDED:
+ session open_session and close_session
+
+USAGE:
+ 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:
+
+ session required pam_namespace.so [arguments]
+
+ This module also depends on pam_selinux.so setting the context.
+
+
+
diff --git a/Linux-PAM/modules/pam_namespace/README.xml b/Linux-PAM/modules/pam_namespace/README.xml
new file mode 100644
index 00000000..98ab7532
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/README.xml
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
+"http://www.docbook.org/xml/4.4/docbookx.dtd">
+<article>
+ <articleinfo>
+ <title>
+ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude"
+ href="pam_namespace.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_namespace-name"]/*)'/>
+ </title>
+ </articleinfo>
+ <section>
+ <programlisting><![CDATA[
+
+pam_namespace module:
+Setup a private namespace with polyinstantiated directories.
+
+THEORY OF OPERATION:
+The pam namespace module consults /etc/security/namespace.conf
+configuration file and sets up a private namespace with polyinstantiated
+directories for a session managed by PAM. A skeleton namespace.conf
+installed by default provides example for polyinstantiating /tmp, /var/tmp
+and users' home directory.
+
+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.
+
+Each line in namespace.conf describes a limit for a user in the form:
+
+<polydir> <instance_prefix> <method> <list_of_uids>
+
+Where:
+<polydir> - is the absolute pathname of the directory to polyinstantiate
+ Special entry $HOME is supported to designate user's home directory.
+ This field cannot be blank.
+
+<instance_prefix> - is the string prefix used to build the pathname for the
+ instantiation of <polydir>. The directory security context, or
+ optionally its md5sum string (32 hex characters), is appended to
+ the prefix 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 $HOME is replaced with
+ the user's home directory, and $USER with the username.
+ This field cannot be blank.
+
+<method> - is the method used for polyinstantiation. It can take 3 different
+ values; "user" for polyinstantiation based on user name, "context"
+ for polyinstantiation based on process security context, and "both"
+ for polyinstantiation based on both user name and security context.
+ Methods "context" and "both" are only available with SELinux. This
+ field cannot be blank.
+
+<list_of_uids> - 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.
+
+EXAMPLE /etc/security/namespace.conf configuration file:
+=======================================================
+# Following three lines will polyinstantiate /tmp, /var/tmp and user's home
+# directories. /tmp and /var/tmp will be polyinstantiated based on both
+# security context as well as user name, whereas home directory will
+# be polyinstantiated based on security context only. 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. The user name and/or context is appended to the instance prefix.
+#
+# Note that instance directories do not have to reside inside 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.
+#
+# Instance parent directories must exist for the polyinstantiation
+# mechanism to work. By default, they should be created with the mode
+# of 000. pam_namespace module will enforce this mode unless it
+# is explicitly called with an argument to ignore the mode of the
+# instance parent. System administrators should use this argument with
+# caution, as it will reduce security and isolation achieved by
+# polyinstantiation.
+#
+/tmp /tmp-inst/ both root,adm
+/var/tmp /var/tmp/tmp-inst/ both root,adm
+$HOME $HOME/$USER.inst/inst- context
+
+ARGUMENTS RECOGNIZED:
+ debug
+ Verbose logging by syslog
+
+ unmnt_remnt
+ 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.
+
+ unmnt_only
+ For trusted programs that want to undo any existing bind mounts
+ and process instance directories on their own, this argument
+ allows them to unmount currently mounted instance directories.
+
+ require_selinux
+ If selinux is not enabled, return failure.
+
+ gen_hash
+ Instead of using the security context string for the instance
+ name, generate and use its md5 hash.
+
+ ignore_config_error
+ 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.
+
+ ignore_instance_parent_mode
+ 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.
+
+MODULE SERVICES PROVIDED:
+ session open_session and close_session
+
+USAGE:
+ 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:
+
+ session required pam_namespace.so [arguments]
+
+ This module also depends on pam_selinux.so setting the context.
+]]>
+ </programlisting>
+ </section>
+</article>
+
diff --git a/Linux-PAM/modules/pam_namespace/md5.c b/Linux-PAM/modules/pam_namespace/md5.c
new file mode 100644
index 00000000..9a060d27
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/md5.c
@@ -0,0 +1,260 @@
+/*
+ * $Id: md5.c,v 1.1 2006/06/27 13:07:43 t8m Exp $
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+#define MD5Name(x) x
+
+#if defined(__i386) || defined(__i386__) || defined(__x86_64) || defined(__x86_64__)
+#define byteReverse(buf, len) /* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301U;
+ ctx->buf[1] = 0xefcdab89U;
+ ctx->buf[2] = 0x98badcfeU;
+ ctx->buf[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *) ctx->in)[14] = ctx->bits[0];
+ ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+void MD5Name(MD5)(unsigned const char *buf, unsigned len, unsigned char digest[16])
+{
+ struct MD5Context ctx;
+ MD5Name(MD5Init)(&ctx);
+ MD5Name(MD5Update)(&ctx, buf, len);
+ MD5Name(MD5Final)(digest, &ctx);
+}
diff --git a/Linux-PAM/modules/pam_namespace/md5.h b/Linux-PAM/modules/pam_namespace/md5.h
new file mode 100644
index 00000000..73f85833
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/md5.h
@@ -0,0 +1,28 @@
+
+#ifndef MD5_H
+#define MD5_H
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+#define MD5_DIGEST_LENGTH 16
+
+void MD5Init(struct MD5Context *);
+void MD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void MD5Final(unsigned char digest[MD5_DIGEST_LENGTH], struct MD5Context *);
+void MD5Transform(uint32 buf[4], uint32 const in[MD5_DIGEST_LENGTH]);
+void MD5(unsigned const char *, unsigned, unsigned char digest[MD5_DIGEST_LENGTH]);
+
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* MD5_H */
diff --git a/Linux-PAM/modules/pam_namespace/namespace.conf b/Linux-PAM/modules/pam_namespace/namespace.conf
new file mode 100644
index 00000000..c7305ffe
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/namespace.conf
@@ -0,0 +1,30 @@
+# /etc/security/namespace.conf
+#
+# See /usr/share/doc/pam-*/txts/README.pam_namespace for more information.
+#
+# Uncommenting the following three lines will polyinstantiate
+# /tmp, /var/tmp and user's home directories. /tmp and /var/tmp will
+# be polyinstantiated based on both security context as well as user
+# name, whereas home directory will be polyinstantiated based on
+# security context only. Polyinstantion will not be performed for
+# user root and adm for directories /tmp and /var/tmp, whereas home
+# directories will be polyinstantiated for all users. The user name
+# and/or context is appended to the instance prefix.
+#
+# Note that instance directories do not have to reside inside 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.
+#
+# Instance parent directories must exist for the polyinstantiation
+# mechanism to work. By default, they should be created with the mode
+# of 000. pam_namespace module will enforce this mode unless it
+# is explicitly called with an argument to ignore the mode of the
+# instance parent. System administrators should use this argument with
+# caution, as it will reduce security and isolation achieved by
+# polyinstantiation.
+#
+#/tmp /tmp-inst/ both root,adm
+#/var/tmp /var/tmp/tmp-inst/ both root,adm
+#$HOME $HOME/$USER.inst/inst- context
diff --git a/Linux-PAM/modules/pam_namespace/namespace.conf.5 b/Linux-PAM/modules/pam_namespace/namespace.conf.5
new file mode 100644
index 00000000..ff325a21
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/namespace.conf.5
@@ -0,0 +1,96 @@
+.\"Generated by db2man.xsl. Don't modify this, modify the source.
+.de Sh \" Subsection
+.br
+.if t .Sp
+.ne 5
+.PP
+\fB\\$1\fR
+.PP
+..
+.de Sp \" Vertical space (when we can't use .PP)
+.if t .sp .5v
+.if n .sp
+..
+.de Ip \" List item
+.br
+.ie \\n(.$>=3 .ne \\$3
+.el .ne 3
+.IP "\\$1" \\$2
+..
+.TH "NAMESPACE.CONF" 5 "" "" ""
+.SH NAME
+namespace.conf \- the namespace configuration file
+.SH "DESCRIPTION"
+
+.PP
+This 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, 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 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\&.
+
+.PP
+When someone logs in, the file \fInamespace\&.conf\fR is scanned where each non comment line represents one polyinstantiated directory with space separated fields as follows:
+
+.PP
+ \fIpolydir\fR \fI instance_prefix\fR \fI method\fR \fI list_of_uids\fR
+
+.PP
+The first field, \fIpolydir\fR, is the absolute pathname of the directory to polyinstantiate\&. Special entry $HOME is supported to designate user's home directory\&. 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>\&. The directory security context, or optionally its md5sum string (32 hex characters), is appended to the prefix 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 $HOME is replaced with the user's home directory, and $USER with the username\&. This field cannot be blank\&. The directory where polyinstantiated instances are to be created, must exist and must have, by default, the mode of 000\&. The requirement that the instance parent be of mode 000 can be overridden with the command line option <ignore_instance_parent_mode>
+
+.PP
+The third field, \fImethod\fR, is the method used for polyinstantiation\&. It can take 3 different values; "user" for polyinstantiation based on user name, "context" for polyinstantiation based on process security context, and "both" for polyinstantiation based on both user name and security context\&. Methods "context" and "both" 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\&.
+
+.SH "EXAMPLES"
+
+.PP
+These are some example lines which might be specified in \fI/etc/security/namespace\&.conf\fR\&.
+
+.nf
+
+ # The following three lines will polyinstantiate /tmp,
+ # /var/tmp and user's home directories\&. /tmp and /var/tmp
+ # will be polyinstantiated based on both security context
+ # as well as user name, whereas home directory will be
+ # polyinstantiated based on security context only\&.
+ # 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\&.
+ #
+ # Note that instance directories do not have to reside inside
+ # 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\&.
+ #
+ /tmp /tmp\-inst/ both root,adm
+ /var/tmp /var/tmp/tmp\-inst/ both root,adm
+ $HOME $HOME/$USER\&.inst/inst\- context
+
+.fi
+
+.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:
+
+.PP
+session required pam_namespace\&.so [arguments]
+
+.PP
+This module also depends on pam_selinux\&.so setting the context\&.
+
+.SH "SEE ALSO"
+
+.PP
+ \fBpam_namespace\fR(8), \fBpam\&.d\fR(5), \fBpam\fR(8)
+
+.SH "AUTHORS"
+
+.PP
+The namespace\&.conf manual page was written by Janak Desai <janak@us\&.ibm\&.com>\&.
+
diff --git a/Linux-PAM/modules/pam_namespace/namespace.conf.5.xml b/Linux-PAM/modules/pam_namespace/namespace.conf.5.xml
new file mode 100644
index 00000000..36a1a085
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/namespace.conf.5.xml
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding='UTF-8'?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+ "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd">
+
+<refentry id="namespace.conf">
+
+ <refmeta>
+ <refentrytitle>namespace.conf</refentrytitle>
+ <manvolnum>5</manvolnum>
+ <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv>
+ <refname>namespace.conf</refname>
+ <refpurpose>the namespace configuration file</refpurpose>
+ </refnamediv>
+
+
+ <refsect1 id='namespace.conf-description'>
+ <title>DESCRIPTION</title>
+
+ <para>
+ This 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, 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 and the instance directory path as its arguments.
+ </para>
+
+ <para>
+ The <filename>/etc/security/namespace.conf</filename> 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.
+ </para>
+
+ <para>
+ When someone logs in, the file <filename>namespace.conf</filename> is
+ scanned where each non comment line represents one polyinstantiated
+ directory with space separated fields as follows:
+ </para>
+
+ <para>
+ <replaceable>polydir</replaceable> <replaceable> instance_prefix</replaceable> <replaceable> method</replaceable> <replaceable> list_of_uids</replaceable>
+ </para>
+
+ <para>
+ The first field, <replaceable>polydir</replaceable>, is the absolute
+ pathname of the directory to polyinstantiate. Special entry $HOME is
+ supported to designate user's home directory. This field cannot be
+ blank.
+ </para>
+
+ <para>
+ The second field, <replaceable>instance_prefix</replaceable> is
+ the string prefix used to build the pathname for the instantiation
+ of &lt;polydir&gt;. The directory security context, or optionally its
+ md5sum string (32 hex characters), is appended to the prefix to
+ generate the final instance directory path. This directory is
+ created if it did not exist already, and is then bind mounted on the
+ &lt;polydir&gt; to provide an instance of &lt;polydir&gt; based on the
+ &lt;method&gt; column. The special string $HOME is replaced with the
+ user's home directory, and $USER with the username. This field cannot
+ be blank. The directory where polyinstantiated instances are to be
+ created, must exist and must have, by default, the mode of 000. The
+ requirement that the instance parent be of mode 000 can be overridden
+ with the command line option &lt;ignore_instance_parent_mode&gt;
+ </para>
+
+ <para>
+ The third field, <replaceable>method</replaceable>, is the method
+ used for polyinstantiation. It can take 3 different values; "user"
+ for polyinstantiation based on user name, "context" for
+ polyinstantiation based on process security context, and "both"
+ for polyinstantiation based on both user name and security context.
+ Methods "context" and "both" are only available with SELinux. This
+ field cannot be blank.
+ </para>
+
+ <para>
+ The fourth field, <replaceable>list_of_uids</replaceable>, 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.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-examples">
+ <title>EXAMPLES</title>
+ <para>
+ These are some example lines which might be specified in
+ <filename>/etc/security/namespace.conf</filename>.
+ </para>
+
+ <literallayout>
+ # The following three lines will polyinstantiate /tmp,
+ # /var/tmp and user's home directories. /tmp and /var/tmp
+ # will be polyinstantiated based on both security context
+ # as well as user name, whereas home directory will be
+ # polyinstantiated based on security context only.
+ # 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.
+ #
+ # Note that instance directories do not have to reside inside
+ # 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.
+ #
+ /tmp /tmp-inst/ both root,adm
+ /var/tmp /var/tmp/tmp-inst/ both root,adm
+ $HOME $HOME/$USER.inst/inst- context
+ </literallayout>
+
+ <para>
+ For the &lt;service&gt;s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/&lt;service&gt; as the last line for
+ session group:
+ </para>
+
+ <para>
+ session required pam_namespace.so [arguments]
+ </para>
+
+ <para>
+ This module also depends on pam_selinux.so setting the context.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="namespace.conf-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry><refentrytitle>pam_namespace</refentrytitle><manvolnum>8</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+ <citerefentry><refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ </para>
+ </refsect1>
+
+ <refsect1 id="namespace.conf-author">
+ <title>AUTHORS</title>
+ <para>
+ The namespace.conf manual page was written by Janak Desai &lt;janak@us.ibm.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/Linux-PAM/modules/pam_namespace/namespace.init b/Linux-PAM/modules/pam_namespace/namespace.init
new file mode 100755
index 00000000..62f8e6e4
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/namespace.init
@@ -0,0 +1,24 @@
+#!/bin/sh
+# This is only a boilerplate for the instance initialization script.
+# It receives polydir path as $1 and the instance path as $2.
+#
+# If you intend to polyinstantiate /tmp and you also want to use the X windows
+# environment, you will have to use this script to bind mount the socket that
+# is used by the X server to communicate with its clients. X server places
+# this socket in /tmp/.X11-unix directory, which will get obscured by
+# polyinstantiation. Uncommenting the following lines will bind mount
+# the relevant directory at an alternative location (/.tmp/.X11-unix) such
+# that the X server, window manager and X clients, can still find the
+# socket X0 at the polyinstanted /tmp/.X11-unix.
+#
+#if [ $1 = /tmp ]; then
+# if [ ! -f /.tmp/.X11-unix ]; then
+# mkdir -p /.tmp/.X11-unix
+# fi
+# mount --bind /tmp/.X11-unix /.tmp/.X11-unix
+# cp -fp -- /tmp/.X0-lock "$2/.X0-lock"
+# mkdir -- "$2/.X11-unix"
+# ln -fs -- /.tmp/.X11-unix/X0 "$2/.X11-unix/X0"
+#fi
+
+exit 0
diff --git a/Linux-PAM/modules/pam_namespace/pam_namespace.8 b/Linux-PAM/modules/pam_namespace/pam_namespace.8
new file mode 100644
index 00000000..126cfc88
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/pam_namespace.8
@@ -0,0 +1,110 @@
+.\" Title: pam_namespace
+.\" Author:
+.\" Generator: DocBook XSL Stylesheets v1.70.1 <http://docbook.sf.net/>
+.\" Date: 06/27/2006
+.\" Manual: Linux\-PAM Manual
+.\" Source: Linux\-PAM Manual
+.\"
+.TH "PAM_NAMESPACE" "8" "06/27/2006" "Linux\-PAM Manual" "Linux\-PAM Manual"
+.\" 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]
+.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 and the instance directory path 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.
+.SH "OPTIONS"
+.TP 3n
+\fBdebug\fR
+A lot of debug information is logged using syslog
+.TP 3n
+\fBunmnt_remnt\fR
+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
+.TP 3n
+\fBunmnt_only\fR
+For trusted programs that want to undo any existing bind mounts and process instance directories on their own, this argument allows them to unmount currently mounted instance directories
+.TP 3n
+\fBrequire_selinux\fR
+If selinux is not enabled, return failure
+.TP 3n
+\fBgen_hash\fR
+Instead of using the security context string for the instance name, generate and use its md5 hash.
+.TP 3n
+\fBignore_config_error\fR
+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.
+.TP 3n
+\fBignore_instance_parent_mode\fR
+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.
+.SH "MODULE SERVICES PROVIDED"
+.PP
+The
+\fBsession\fR
+service is supported.
+.SH "RETURN VALUES"
+.TP 3n
+PAM_SUCCESS
+Namespace setup was successful.
+.TP 3n
+PAM_SERVICE_ERR
+Unexpected system error occurred while setting up namespace.
+.TP 3n
+PAM_SESSION_ERR
+Unexpected namespace configuration error occurred.
+.SH "FILES"
+.TP 3n
+\fI/etc/security/namespace.conf\fR
+Configuration file
+.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:
+.PP
+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:
+.PP
+
+.sp
+.RS 3n
+.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
+ 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
+ "AlwaysRestartServer=true", and it is not overridden by
+ /etc/gdm/custom.conf.
+
+.fi
+.RE
+.sp
+.SH "SEE ALSO"
+.PP
+
+\fBnamespace.conf\fR(5),
+\fBpam.d\fR(8),
+\fBmount\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>.
diff --git a/Linux-PAM/modules/pam_namespace/pam_namespace.8.xml b/Linux-PAM/modules/pam_namespace/pam_namespace.8.xml
new file mode 100644
index 00000000..4c93ecf0
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/pam_namespace.8.xml
@@ -0,0 +1,317 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+ "http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd">
+
+<refentry id='pam_namespace'>
+
+ <refmeta>
+ <refentrytitle>pam_namespace</refentrytitle>
+ <manvolnum>8</manvolnum>
+ <refmiscinfo class='setdesc'>Linux-PAM Manual</refmiscinfo>
+ </refmeta>
+
+ <refnamediv id='pam_namespace-name'>
+ <refname>pam_namespace</refname>
+ <refpurpose>
+ PAM module for configuring namespace for a session
+ </refpurpose>
+ </refnamediv>
+
+<!-- body begins here -->
+
+ <refsynopsisdiv>
+ <cmdsynopsis id="pam_namespace-cmdsynopsis">
+ <command>pam_namespace.so</command>
+ <arg choice="opt">
+ debug
+ </arg>
+ <arg choice="opt">
+ unmnt_remnt
+ </arg>
+ <arg choice="opt">
+ unmnt_only
+ </arg>
+ <arg choice="opt">
+ require_selinux
+ </arg>
+ <arg choice="opt">
+ gen_hash
+ </arg>
+ <arg choice="opt">
+ ignore_config_error
+ </arg>
+ <arg choice="opt">
+ ignore_instance_parent_mode
+ </arg>
+ </cmdsynopsis>
+ </refsynopsisdiv>
+
+
+ <refsect1 id="pam_namespace-description">
+ <title>DESCRIPTION</title>
+ <para>
+ 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 <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 and the instance directory path as its arguments.
+ </para>
+
+ <para>
+ 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.
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_namespace-options">
+ <title>OPTIONS</title>
+ <variablelist>
+
+ <varlistentry>
+ <term>
+ <option>debug</option>
+ </term>
+ <listitem>
+ <para>
+ A lot of debug information is logged using syslog
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_remnt</option>
+ </term>
+ <listitem>
+ <para>
+ 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
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>unmnt_only</option>
+ </term>
+ <listitem>
+ <para>
+ For trusted programs that want to undo any
+ existing bind mounts and process instance
+ directories on their own, this argument allows
+ them to unmount currently mounted instance
+ directories
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>require_selinux</option>
+ </term>
+ <listitem>
+ <para>
+ If selinux is not enabled, return failure
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>gen_hash</option>
+ </term>
+ <listitem>
+ <para>
+ Instead of using the security context string
+ for the instance name, generate and use its
+ md5 hash.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore_config_error</option>
+ </term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
+ <term>
+ <option>ignore_instance_parent_mode</option>
+ </term>
+ <listitem>
+ <para>
+ 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.
+ </para>
+ </listitem>
+ </varlistentry>
+
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-services">
+ <title>MODULE SERVICES PROVIDED</title>
+ <para>
+ The <option>session</option> service is supported.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-return_values">
+ <title>RETURN VALUES</title>
+ <variablelist>
+ <varlistentry>
+ <term>PAM_SUCCESS</term>
+ <listitem>
+ <para>
+ Namespace setup was successful.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SERVICE_ERR</term>
+ <listitem>
+ <para>
+ Unexpected system error occurred while setting up namespace.
+ </para>
+ </listitem>
+ </varlistentry>
+ <varlistentry>
+ <term>PAM_SESSION_ERR</term>
+ <listitem>
+ <para>
+ Unexpected namespace configuration error occurred.
+ </para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-files">
+ <title>FILES</title>
+ <variablelist>
+ <varlistentry>
+ <term><filename>/etc/security/namespace.conf</filename></term>
+ <listitem>
+ <para>Configuration file</para>
+ </listitem>
+ </varlistentry>
+ </variablelist>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-examples">
+ <title>EXAMPLES</title>
+
+ <para>
+ For the &lt;service&gt;s you need polyinstantiation (login for example)
+ put the following line in /etc/pam.d/&lt;service&gt; as the last line for
+ session group:
+ </para>
+
+ <para>
+ session required pam_namespace.so [arguments]
+ </para>
+
+ <para>
+ To use polyinstantiation with graphical display manager gdm, insert the
+ following line, before exit 0, in /etc/gdm/PostSession/Default:
+ </para>
+
+ <para>
+ /usr/sbin/gdm-safe-restart
+ </para>
+
+ <para>
+ 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
+ <filename>/etc/security/namespace.init</filename> 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
+ <filename>/etc/security/namespace.init</filename>. In addition,
+ perform the following changes to use graphical environment with
+ polyinstantiation of /tmp:
+ </para>
+
+ <para>
+ <literallayout>
+ 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
+ "AlwaysRestartServer=true", and it is not overridden by
+ /etc/gdm/custom.conf.
+ </literallayout>
+ </para>
+
+ </refsect1>
+
+ <refsect1 id="pam_namespace-see_also">
+ <title>SEE ALSO</title>
+ <para>
+ <citerefentry>
+ <refentrytitle>namespace.conf</refentrytitle><manvolnum>5</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>mount</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>,
+ <citerefentry>
+ <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
+ </citerefentry>.
+ </para>
+ </refsect1>
+
+ <refsect1 id="pam_namespace-authors">
+ <title>AUTHORS</title>
+ <para>
+ The namespace setup scheme was designed by Stephen Smalley, Janak Desai
+ and Chad Sellers.
+ The pam_namespace PAM module was developed by Janak Desai &lt;janak@us.ibm.com&gt;, Chad Sellers &lt;csellers@tresys.com&gt; and Steve Grubb &lt;sgrubb@redhat.com&gt;.
+ </para>
+ </refsect1>
+</refentry>
diff --git a/Linux-PAM/modules/pam_namespace/pam_namespace.c b/Linux-PAM/modules/pam_namespace/pam_namespace.c
new file mode 100644
index 00000000..e4e4a5d8
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/pam_namespace.c
@@ -0,0 +1,1337 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default namespace after
+ * establishing a session via PAM.
+ *
+ * (C) Copyright IBM Corporation 2005
+ * (C) Copyright Red Hat 2006
+ * All Rights Reserved.
+ *
+ * Written by: Janak Desai <janak@us.ibm.com>
+ * With Revisions by: Steve Grubb <sgrubb@redhat.com>
+ * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include "pam_namespace.h"
+
+/*
+ * Copies the contents of ent into pent
+ */
+static int copy_ent(const struct polydir_s *ent, struct polydir_s *pent)
+{
+ unsigned int i;
+
+ strcpy(pent->dir, ent->dir);
+ strcpy(pent->instance_prefix, ent->instance_prefix);
+ pent->method = ent->method;
+ pent->num_uids = ent->num_uids;
+ if (ent->num_uids) {
+ uid_t *pptr, *eptr;
+
+ pent->uid = (uid_t *) malloc(ent->num_uids * sizeof(uid_t));
+ if (!(pent->uid)) {
+ return -1;
+ }
+ for (i = 0, pptr = pent->uid, eptr = ent->uid; i < ent->num_uids;
+ i++, eptr++, pptr++)
+ *pptr = *eptr;
+ } else
+ pent->uid = NULL;
+ return 0;
+}
+
+/*
+ * Adds an entry for a polyinstantiated directory to the linked list of
+ * polyinstantiated directories. It is called from process_line() while
+ * parsing the namespace configuration file.
+ */
+static int add_polydir_entry(struct instance_data *idata,
+ const struct polydir_s *ent)
+{
+ struct polydir_s *pent;
+ int rc = 0;
+
+ /*
+ * Allocate an entry to hold information about a directory to
+ * polyinstantiate, populate it with information from 2nd argument
+ * and add the entry to the linked list of polyinstantiated
+ * directories.
+ */
+ pent = (struct polydir_s *) malloc(sizeof(struct polydir_s));
+ if (!pent) {
+ rc = -1;
+ goto out;
+ }
+ /* Make copy */
+ rc = copy_ent(ent,pent);
+ if(rc < 0)
+ goto out_clean;
+
+ /* Now attach to linked list */
+ pent->next = NULL;
+ if (idata->polydirs_ptr == NULL)
+ idata->polydirs_ptr = pent;
+ else {
+ struct polydir_s *tail;
+
+ tail = idata->polydirs_ptr;
+ while (tail->next)
+ tail = tail->next;
+ tail->next = pent;
+ }
+ goto out;
+out_clean:
+ free(pent);
+out:
+ return rc;
+}
+
+
+/*
+ * Deletes all the entries in the linked list.
+ */
+static void del_polydir_list(struct polydir_s *polydirs_ptr)
+{
+ struct polydir_s *dptr = polydirs_ptr;
+
+ while (dptr) {
+ struct polydir_s *tptr = dptr;
+ dptr = dptr->next;
+ free(tptr->uid);
+ free(tptr);
+ }
+}
+
+
+/*
+ * Called from parse_config_file, this function processes a single line
+ * of the namespace configuration file. It skips over comments and incomplete
+ * or malformed lines. It processes a valid line with information on
+ * polyinstantiating a directory by populating appropriate fields of a
+ * polyinstatiated directory structure and then calling add_polydir_entry to
+ * add that entry to the linked list of polyinstantiated directories.
+ */
+static int process_line(char *line, const char *home,
+ struct instance_data *idata)
+{
+ const char *dir, *instance_prefix;
+ const char *method, *uids;
+ char *tptr;
+ struct polydir_s poly;
+ int retval = 0;
+
+ poly.uid = NULL;
+ poly.num_uids = 0;
+
+ /*
+ * skip the leading white space
+ */
+ while (*line && isspace(*line))
+ line++;
+
+ /*
+ * Rip off the comments
+ */
+ tptr = strchr(line,'#');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Rip off the newline char
+ */
+ tptr = strchr(line,'\n');
+ if (tptr)
+ *tptr = '\0';
+
+ /*
+ * Anything left ?
+ */
+ if (line[0] == 0)
+ return 0;
+
+ /*
+ * Initialize and scan the five strings from the line from the
+ * namespace configuration file.
+ */
+ dir = strtok_r(line, " \t", &tptr);
+ if (dir == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing polydir");
+ goto skipping;
+ }
+ instance_prefix = strtok_r(NULL, " \t", &tptr);
+ if (instance_prefix == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing instance_prefix");
+ goto skipping;
+ }
+ method = strtok_r(NULL, " \t", &tptr);
+ if (method == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Invalid line missing method");
+ goto skipping;
+ }
+
+ /*
+ * Only the uids field is allowed to be blank, to indicate no
+ * override users for polyinstantiation of that directory. If
+ * any of the other fields are blank, the line is incomplete so
+ * skip it.
+ */
+ uids = strtok_r(NULL, " \t", &tptr);
+
+ /*
+ * If the directory being polyinstantiated is the home directory
+ * of the user who is establishing a session, we have to swap
+ * the "$HOME" string with the user's home directory that is
+ * passed in as an argument.
+ */
+ if (strcmp(dir, "$HOME") == 0) {
+ dir = home;
+ }
+
+ /*
+ * Expand $HOME and $USER in instance dir prefix
+ */
+ if ((tptr = strstr(instance_prefix, "$USER")) != 0) {
+ /* FIXME: should only support this if method is USER or BOTH */
+ char *expanded = alloca(strlen(idata->user) + strlen(instance_prefix)-5+1);
+ *tptr = 0;
+ sprintf(expanded, "%s%s%s", instance_prefix, idata->user, tptr+5);
+ instance_prefix = expanded;
+ }
+ if ((tptr = strstr(instance_prefix, "$HOME")) != 0) {
+ char *expanded = alloca(strlen(home)+strlen(instance_prefix)-5+1);
+ *tptr = 0;
+ sprintf(expanded, "%s%s%s", instance_prefix, home, tptr+5);
+ instance_prefix = expanded;
+ }
+
+ /*
+ * Ensure that all pathnames are absolute path names.
+ */
+ if ((dir[0] != '/') || (instance_prefix[0] != '/')) {
+ pam_syslog(idata->pamh, LOG_NOTICE,"Pathnames must start with '/'");
+ goto skipping;
+ }
+ if (strstr(dir, "..") || strstr(instance_prefix, "..")) {
+ pam_syslog(idata->pamh, LOG_NOTICE,"Pathnames must not contain '..'");
+ goto skipping;
+ }
+
+ /*
+ * Populate polyinstantiated directory structure with appropriate
+ * pathnames and the method with which to polyinstantiate.
+ */
+ if (strlen(dir) >= sizeof(poly.dir)
+ || strlen(instance_prefix) >= sizeof(poly.instance_prefix)) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Pathnames too long");
+ }
+ strcpy(poly.dir, dir);
+ strcpy(poly.instance_prefix, instance_prefix);
+ if (strcmp(method, "user") == 0)
+ poly.method = USER;
+#ifdef WITH_SELINUX
+ else if (strcmp(method, "context") == 0) {
+ if (idata->flags & PAMNS_CTXT_BASED_INST)
+ poly.method = CONTEXT;
+ else
+ poly.method = USER;
+ } else if (strcmp(method, "both") == 0) {
+ if (idata->flags & PAMNS_CTXT_BASED_INST)
+ poly.method = BOTH;
+ else
+ poly.method = USER;
+ }
+
+#endif
+ else {
+ pam_syslog(idata->pamh, LOG_NOTICE, "Illegal method");
+ goto skipping;
+ }
+
+ /*
+ * If the line in namespace.conf for a directory to polyinstantiate
+ * contains a list of override users (users for whom polyinstantiation
+ * is not performed), read the user ids, convert names into uids, and
+ * add to polyinstantiated directory structure.
+ */
+ if (uids) {
+ uid_t *uidptr;
+ const char *ustr, *sstr;
+ int count, i;
+
+ for (count = 0, ustr = sstr = uids; sstr; ustr = sstr + 1, count++)
+ sstr = strchr(ustr, ',');
+
+ poly.num_uids = count;
+ poly.uid = (uid_t *) malloc(count * sizeof (uid_t));
+ uidptr = poly.uid;
+ if (uidptr == NULL) {
+ pam_syslog(idata->pamh, LOG_NOTICE, "out of memory");
+ goto skipping;
+ }
+
+ ustr = uids;
+ for (i = 0; i < count; i++) {
+ struct passwd *pwd;
+
+ tptr = strchr(ustr, ',');
+ if (tptr)
+ *tptr = '\0';
+
+ pwd = pam_modutil_getpwnam(idata->pamh, ustr);
+ *uidptr = pwd->pw_uid;
+ if (i < count - 1) {
+ ustr = tptr + 1;
+ uidptr++;
+ }
+ }
+ }
+
+ /*
+ * Add polyinstantiated directory structure to the linked list
+ * of all polyinstantiated directory structures.
+ */
+ if (add_polydir_entry(idata, &poly) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Allocation Error");
+ retval = PAM_SERVICE_ERR;
+ }
+ free(poly.uid);
+
+ goto out;
+
+skipping:
+ if (idata->flags & PAMNS_IGN_CONFIG_ERR)
+ retval = 0;
+ else
+ retval = PAM_SERVICE_ERR;
+out:
+ return retval;
+}
+
+
+/*
+ * Parses /etc/security/namespace.conf file to build a linked list of
+ * polyinstantiated directory structures of type polydir_s. Each entry
+ * in the linked list contains information needed to polyinstantiate
+ * one directory.
+ */
+static int parse_config_file(struct instance_data *idata)
+{
+ FILE *fil;
+ char *home;
+ struct passwd *cpwd;
+ char *line = NULL;
+ int retval;
+ size_t len = 0;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Parsing config file %s",
+ PAM_NAMESPACE_CONFIG);
+
+ /*
+ * Extract the user's home directory to resolve $HOME entries
+ * in the namespace configuration file.
+ */
+ cpwd = pam_modutil_getpwnam(idata->pamh, idata->user);
+ if (!cpwd) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting home dir for '%s'", idata->user);
+ return PAM_SESSION_ERR;
+ }
+ home = strdupa(cpwd->pw_dir);
+
+ /*
+ * Open configuration file, read one line at a time and call
+ * process_line to process each line.
+ */
+ fil = fopen(PAM_NAMESPACE_CONFIG, "r");
+ if (fil == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening config file");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Use unlocked IO */
+ __fsetlocking(fil, FSETLOCKING_BYCALLER);
+
+ /* loop reading the file */
+ while (getline(&line, &len, fil) > 0) {
+ retval = process_line(line, home, idata);
+ if (retval) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error processing conf file line %s", line);
+ fclose(fil);
+ free(line);
+ return PAM_SERVICE_ERR;
+ }
+ }
+ fclose(fil);
+ free(line);
+
+ /* All done...just some debug stuff */
+ if (idata->flags & PAMNS_DEBUG) {
+ struct polydir_s *dptr = idata->polydirs_ptr;
+ uid_t *iptr;
+ uid_t i;
+
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ dptr?"Configured poly dirs:":"No configured poly dirs");
+ while (dptr) {
+ pam_syslog(idata->pamh, LOG_DEBUG, "dir='%s' iprefix='%s' meth=%d",
+ dptr->dir, dptr->instance_prefix, dptr->method);
+ for (i = 0, iptr = dptr->uid; i < dptr->num_uids; i++, iptr++)
+ pam_syslog(idata->pamh, LOG_DEBUG, "override user %d ", *iptr);
+ dptr = dptr->next;
+ }
+ }
+
+ return PAM_SUCCESS;
+}
+
+
+/*
+ * This funtion returns true if a given uid is present in the polyinstantiated
+ * directory's list of override uids. If the uid is one of the override
+ * uids for the polyinstantiated directory, polyinstantiation is not
+ * performed for that user for that directory.
+ */
+static int ns_override(struct polydir_s *polyptr, struct instance_data *idata)
+{
+ unsigned int i;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Checking for ns override in dir %s for uid %d",
+ polyptr->dir, idata->uid);
+
+ for (i = 0; i < polyptr->num_uids; i++) {
+ if (idata->uid == polyptr->uid[i]) {
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+#ifdef WITH_SELINUX
+static int form_context(const struct polydir_s *polyptr,
+ security_context_t *i_context, security_context_t *origcon,
+ struct instance_data *idata)
+{
+ int rc = PAM_SUCCESS;
+ security_context_t scon = NULL;
+ security_class_t tclass;
+
+ /*
+ * Get the security context of the directory to polyinstantiate.
+ */
+ rc = getfilecon(polyptr->dir, origcon);
+ if (rc < 0 || *origcon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting poly dir context, %m");
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * If polyinstantiating based on security context, get current
+ * process security context, get security class for directories,
+ * and ask the policy to provide security context of the
+ * polyinstantiated instance directory.
+ */
+ if ((polyptr->method == CONTEXT) || (polyptr->method == BOTH)) {
+ rc = getexeccon(&scon);
+ if (rc < 0 || scon == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error getting exec context, %m");
+ return PAM_SESSION_ERR;
+ }
+ tclass = string_to_security_class("dir");
+
+ if (security_compute_member(scon, *origcon, tclass,
+ i_context) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error computing poly dir member context");
+ freecon(scon);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "member context returned by policy %s", *i_context);
+ freecon(scon);
+ }
+ return PAM_SUCCESS;
+}
+#endif
+
+/*
+ * poly_name returns the name of the polyinstantiated instance directory
+ * based on the method used for polyinstantiation (user, context or both)
+ * In addition, the function also returns the security contexts of the
+ * original directory to polyinstantiate and the polyinstantiated instance
+ * directory.
+ */
+#ifdef WITH_SELINUX
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ security_context_t *i_context, security_context_t *origcon,
+ struct instance_data *idata)
+#else
+static int poly_name(const struct polydir_s *polyptr, char **i_name,
+ struct instance_data *idata)
+#endif
+{
+ int rc;
+
+# ifdef WITH_SELINUX
+ rc = form_context(polyptr, i_context, origcon, idata);
+#endif
+ rc = PAM_SUCCESS;
+
+ /*
+ * Set the name of the polyinstantiated instance dir based on the
+ * polyinstantiation method.
+ */
+ switch (polyptr->method) {
+ case USER:
+ if (asprintf(i_name, "%s", idata->user) < 0) {
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ }
+ break;
+
+#ifdef WITH_SELINUX
+ case CONTEXT:
+ if (asprintf(i_name, "%s", *i_context) < 0) {
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ }
+ break;
+
+ case BOTH:
+ if (asprintf(i_name, "%s_%s", *i_context, idata->user) < 0) {
+ *i_name = NULL;
+ rc = PAM_SESSION_ERR;
+ }
+ break;
+#endif /* WITH_SELINUX */
+
+ default:
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR, "Unknown method");
+ rc = PAM_SESSION_ERR;
+ }
+
+ if ((idata->flags & PAMNS_DEBUG) && rc == PAM_SUCCESS)
+ pam_syslog(idata->pamh, LOG_DEBUG, "poly_name %s", *i_name);
+
+ return rc;
+}
+
+static int check_inst_parent(char *ipath, struct instance_data *idata)
+{
+ struct stat instpbuf;
+ char *inst_parent, *trailing_slash;
+ /*
+ * stat the instance parent path to make sure it exists
+ * and is a directory. Check that its mode is 000 (unless the
+ * admin explicitly instructs to ignore the instance parent
+ * mode by the "ignore_instance_parent_mode" argument).
+ */
+ inst_parent = (char *) malloc(strlen(ipath)+1);
+ if (!inst_parent) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error allocating pathname string");
+ return PAM_SESSION_ERR;
+ }
+
+ strcpy(inst_parent, ipath);
+ trailing_slash = strrchr(inst_parent, '/');
+ 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;
+ }
+
+ /*
+ * 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);
+ 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",
+ inst_parent);
+ free(inst_parent);
+ return PAM_SESSION_ERR;
+ }
+ }
+ free(inst_parent);
+ return PAM_SUCCESS;
+}
+
+/*
+* 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.
+*/
+static int inst_init(const struct polydir_s *polyptr, char *ipath,
+ struct instance_data *idata)
+{
+ pid_t rc, pid;
+ sighandler_t osighand = NULL;
+ int status;
+
+ osighand = signal(SIGCHLD, SIG_DFL);
+ if (osighand == SIG_ERR) {
+ pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+
+ if (access(NAMESPACE_INIT_SCRIPT, F_OK) == 0) {
+ if (access(NAMESPACE_INIT_SCRIPT, X_OK) < 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Namespace init script not executable");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ } else {
+ pid = fork();
+ if (pid == 0) {
+#ifdef WITH_SELINUX
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ if (setexeccon(NULL) < 0)
+ exit(1);
+ }
+#endif
+ if (execl(NAMESPACE_INIT_SCRIPT, NAMESPACE_INIT_SCRIPT,
+ polyptr->dir, ipath, (char *)NULL) < 0)
+ 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");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ if (!WIFEXITED(status) || WIFSIGNALED(status) > 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error initializing instance");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ } else if (pid < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Cannot fork to run namespace init script, %m");
+ rc = PAM_SESSION_ERR;
+ goto out;
+ }
+ }
+ }
+ rc = PAM_SUCCESS;
+out:
+ (void) signal(SIGCHLD, osighand);
+
+ return rc;
+}
+
+/*
+ * Create polyinstantiated instance directory (ipath).
+ */
+#ifdef WITH_SELINUX
+static int create_dirs(const struct polydir_s *polyptr, char *ipath,
+ security_context_t icontext, security_context_t ocontext,
+ struct instance_data *idata)
+#else
+static int create_dirs(const struct polydir_s *polyptr, char *ipath,
+ struct instance_data *idata)
+#endif
+{
+ struct stat statbuf, newstatbuf;
+ int rc, fd;
+
+ /*
+ * stat the directory to polyinstantiate, so its owner-group-mode
+ * can be propagated to instance directory
+ */
+ rc = PAM_SUCCESS;
+ if (stat(polyptr->dir, &statbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Make sure we are dealing with a directory
+ */
+ if (!S_ISDIR(statbuf.st_mode)) {
+ pam_syslog(idata->pamh, LOG_ERR, "poly dir %s is not a dir",
+ polyptr->dir);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Check to make sure instance parent is valid.
+ */
+ if (check_inst_parent(ipath, idata))
+ return PAM_SESSION_ERR;
+
+ /*
+ * Create instance directory and set its security context to the context
+ * returned by the security policy. Set its mode and ownership
+ * attributes to match that of the original directory that is being
+ * polyinstantiated.
+ */
+ if (mkdir(ipath, S_IRUSR) < 0) {
+ if (errno == EEXIST)
+ goto inst_init;
+ else {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating %s, %m",
+ ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+
+ /* Open a descriptor to it to prevent races */
+ fd = open(ipath, O_DIRECTORY | O_RDONLY);
+ if (fd < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error opening %s, %m", ipath);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+#ifdef WITH_SELINUX
+ /* If SE Linux is disabled, no need to label it */
+ if (idata->flags & PAMNS_SELINUX_ENABLED) {
+ /* If method is USER, icontext is NULL */
+ if (icontext) {
+ if (fsetfilecon(fd, icontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, icontext);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ } else {
+ if (fsetfilecon(fd, ocontext) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error setting context of %s to %s", ipath, ocontext);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+#endif
+ if (fstat(fd, &newstatbuf) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error stating %s, %m",
+ ipath);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ if (newstatbuf.st_uid != statbuf.st_uid ||
+ newstatbuf.st_gid != statbuf.st_gid) {
+ if (fchown(fd, statbuf.st_uid, statbuf.st_gid) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Error changing owner for %s, %m",
+ ipath);
+ close(fd);
+ rmdir(ipath);
+ return PAM_SESSION_ERR;
+ }
+ }
+ if (fchmod(fd, statbuf.st_mode & 07777) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error changing mode for %s, %m",
+ ipath);
+ close(fd);
+ rmdir(ipath);
+ 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:
+ rc = inst_init(polyptr, ipath, idata);
+ return rc;
+}
+
+
+/*
+ * md5hash generates a hash of the passed in instance directory name.
+ */
+static int md5hash(char **instname, struct instance_data *idata)
+{
+ int i;
+ char *md5inst = NULL;
+ char *to;
+ unsigned char inst_digest[MD5_DIGEST_LENGTH];
+
+ /*
+ * Create MD5 hashes for instance pathname.
+ */
+
+ MD5((unsigned char *)*instname, strlen(*instname), inst_digest);
+
+ if ((md5inst = malloc(MD5_DIGEST_LENGTH * 2 + 1)) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unable to allocate buffer");
+ return PAM_SESSION_ERR;
+ }
+
+ to = md5inst;
+ for (i = 0; i < MD5_DIGEST_LENGTH; i++) {
+ snprintf(to, 3, "%02x", (unsigned int)inst_digest[i]);
+ to += 3;
+ }
+
+ free(*instname);
+ *instname = md5inst;
+
+ 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
+ * security attributes, and performs bind mount to setup the process
+ * namespace.
+ */
+static int ns_setup(const struct polydir_s *polyptr,
+ struct instance_data *idata)
+{
+ int retval = 0;
+ char *inst_dir = NULL;
+ char *instname = NULL;
+ char *dir;
+#ifdef WITH_SELINUX
+ security_context_t instcontext = NULL, origcontext = NULL;
+#endif
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Set namespace for directory %s", polyptr->dir);
+
+ dir = strrchr(polyptr->dir, '/');
+ if (dir && strlen(dir) > 1)
+ dir++;
+
+ /*
+ * Obtain the name of instance pathname based on the
+ * polyinstantiation method and instance context returned by
+ * security policy.
+ */
+#ifdef WITH_SELINUX
+ retval = poly_name(polyptr, &instname, &instcontext,
+ &origcontext, idata);
+#else
+ retval = poly_name(polyptr, &instname, idata);
+#endif
+
+ if (retval) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error getting instance name");
+ goto error_out;
+ } else {
+#ifdef WITH_SELINUX
+ if ((idata->flags & PAMNS_DEBUG) &&
+ (idata->flags & PAMNS_SELINUX_ENABLED))
+ pam_syslog(idata->pamh, LOG_DEBUG, "Inst ctxt %s Orig ctxt %s",
+ instcontext, origcontext);
+#endif
+ }
+
+ if (idata->flags & PAMNS_GEN_HASH) {
+ retval = md5hash(&instname, idata);
+ if (retval < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error generating md5 hash");
+ goto error_out;
+ }
+ }
+
+ if (asprintf(&inst_dir, "%s%s", polyptr->instance_prefix, instname) < 0)
+ goto error_out;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "instance_dir %s",
+ inst_dir);
+
+ /*
+ * Create instance directory with appropriate security
+ * contexts, owner, group and mode bits.
+ */
+#ifdef WITH_SELINUX
+ retval = create_dirs(polyptr, inst_dir, instcontext,
+ origcontext, idata);
+#else
+ retval = create_dirs(polyptr, inst_dir, idata);
+#endif
+
+ if (retval < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error creating instance dir");
+ goto error_out;
+ }
+
+ /*
+ * Bind mount instance directory on top of the polyinstantiated
+ * directory to provide an instance of polyinstantiated directory
+ * based on polyinstantiated method.
+ */
+ if (mount(inst_dir, polyptr->dir, NULL, MS_BIND, NULL) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Error mounting %s on %s, %m",
+ inst_dir, polyptr->dir);
+ goto error_out;
+ }
+
+ goto cleanup;
+
+ /*
+ * various error exit points. Free allocated memory and set return
+ * value to indicate a pam session error.
+ */
+error_out:
+ retval = PAM_SESSION_ERR;
+
+cleanup:
+ free(inst_dir);
+ free(instname);
+#ifdef WITH_SELINUX
+ freecon(instcontext);
+ freecon(origcontext);
+#endif
+ return retval;
+}
+
+
+/*
+ * This function checks to see if the current working directory is
+ * inside the directory passed in as the first argument.
+ */
+static int cwd_in(char *dir, struct instance_data *idata)
+{
+ int retval = 0;
+ char cwd[PATH_MAX];
+
+ if (getcwd(cwd, PATH_MAX) == NULL) {
+ pam_syslog(idata->pamh, LOG_ERR, "Can't get current dir, %m");
+ return -1;
+ }
+
+ if (strncmp(cwd, dir, strlen(dir)) == 0) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is inside %s", dir);
+ retval = 1;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "cwd is outside %s", dir);
+ }
+
+ return retval;
+}
+
+
+/*
+ * This function checks to see if polyinstantiation is needed for any
+ * of the directories listed in the configuration file. If needed,
+ * cycles through all polyinstantiated directory entries and calls
+ * ns_setup to setup polyinstantiation for each one of them.
+ */
+static int setup_namespace(struct instance_data *idata, enum unmnt_op unmnt)
+{
+ int retval = 0, need_poly = 0, changing_dir = 0;
+ char *cptr, *fptr, poly_parent[PATH_MAX];
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Set up namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directory entries to see if
+ * polyinstantiation is needed at all.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata)) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Overriding poly for user %d for dir %s",
+ idata->uid, pptr->dir);
+ continue;
+ } else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Need poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+ need_poly = 1;
+ break;
+ }
+ }
+
+ /*
+ * If polyinstnatiation is needed, call the unshare system call to
+ * disassociate from the parent namespace.
+ */
+ if (need_poly) {
+ if (unshare(CLONE_NEWNS) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Unable to unshare from parent namespace, %m");
+ return PAM_SESSION_ERR;
+ }
+ } else
+ return PAM_SUCCESS;
+
+ /*
+ * Again cycle through all polyinstantiated directories, this time,
+ * call ns_setup to setup polyinstantiation for a particular entry.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata))
+ continue;
+ else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Setting poly ns for user %d for dir %s",
+ idata->uid, pptr->dir);
+
+ if ((unmnt == UNMNT_REMNT) || (unmnt == UNMNT_ONLY)) {
+ /*
+ * Check to see if process current directory is in the
+ * bind mounted instance_parent directory that we are trying to
+ * umount
+ */
+ if ((changing_dir = cwd_in(pptr->dir, idata)) < 0) {
+ return PAM_SESSION_ERR;
+ } else if (changing_dir) {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "changing cwd");
+
+ /*
+ * Change current working directory to the parent of
+ * the mount point, that is parent of the orig
+ * directory where original contents of the polydir
+ * are available from
+ */
+ strcpy(poly_parent, pptr->dir);
+ fptr = strchr(poly_parent, '/');
+ cptr = strrchr(poly_parent, '/');
+ if (fptr && cptr && (fptr == cptr))
+ strcpy(poly_parent, "/");
+ else if (cptr)
+ *cptr = '\0';
+ if (chdir(poly_parent) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR,
+ "Can't chdir to %s, %m", poly_parent);
+ }
+ }
+
+ if (umount(pptr->dir) < 0) {
+ int saved_errno = errno;
+ pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
+ pptr->dir);
+ if (saved_errno != EINVAL)
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Umount succeeded %s",
+ pptr->dir);
+ }
+
+ if (unmnt != UNMNT_ONLY) {
+ retval = ns_setup(pptr, idata);
+ if (retval != PAM_SUCCESS)
+ break;
+ }
+ }
+ }
+
+ return retval;
+}
+
+
+/*
+ * Orig namespace. This function is called from when closing a pam
+ * session. If authorized, it unmounts instance directory.
+ */
+static int orig_namespace(struct instance_data *idata)
+{
+ struct polydir_s *pptr;
+
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "orig namespace for pid %d",
+ getpid());
+
+ /*
+ * Cycle through all polyinstantiated directories from the namespace
+ * configuration file to see if polyinstantiation was performed for
+ * this user for each of the entry. If it was, try and unmount
+ * appropriate polyinstantiated instance directories.
+ */
+ for (pptr = idata->polydirs_ptr; pptr; pptr = pptr->next) {
+ if (ns_override(pptr, idata))
+ continue;
+ else {
+ if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG,
+ "Unmounting instance dir for user %d & dir %s",
+ idata->uid, pptr->dir);
+
+ if (umount(pptr->dir) < 0) {
+ pam_syslog(idata->pamh, LOG_ERR, "Unmount of %s failed, %m",
+ pptr->dir);
+ return PAM_SESSION_ERR;
+ } else if (idata->flags & PAMNS_DEBUG)
+ pam_syslog(idata->pamh, LOG_DEBUG, "Unmount of %s succeeded",
+ pptr->dir);
+ }
+ }
+ return 0;
+}
+
+
+#ifdef WITH_SELINUX
+/*
+ * This function checks if the calling program has requested context
+ * change by calling setexeccon(). If context change is not requested
+ * then it does not make sense to polyinstantiate based on context.
+ * The return value from this function is used when selecting the
+ * polyinstantiation method. If context change is not requested then
+ * the polyinstantiation method is set to USER, even if the configuration
+ * file lists the method as "context" or "both".
+ */
+static int ctxt_based_inst_needed(void)
+{
+ security_context_t scon = NULL;
+ int rc = 0;
+
+ rc = getexeccon(&scon);
+ if (rc < 0 || scon == NULL)
+ return 0;
+ else {
+ freecon(scon);
+ return 1;
+ }
+}
+#endif
+
+
+/*
+ * Entry point from pam_open_session call.
+ */
+PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ char *user_name;
+ struct passwd *pwd;
+ enum unmnt_op unmnt = NO_UNMNT;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "gen_hash") == 0)
+ idata.flags |= PAMNS_GEN_HASH;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ if (strcmp(argv[i], "ignore_instance_parent_mode") == 0)
+ idata.flags |= PAMNS_IGN_INST_PARENT_MODE;
+ if (strcmp(argv[i], "unmnt_remnt") == 0)
+ unmnt = UNMNT_REMNT;
+ if (strcmp(argv[i], "unmnt_only") == 0)
+ unmnt = UNMNT_ONLY;
+ if (strcmp(argv[i], "require_selinux") == 0) {
+ if (~(idata.flags & PAMNS_SELINUX_ENABLED)) {
+ pam_syslog(idata.pamh, LOG_ERR,
+ "selinux_required option given and selinux is disabled");
+ return PAM_SESSION_ERR;
+ }
+ }
+ }
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "open_session - start");
+
+ /*
+ * Lookup user and fill struct items
+ */
+ retval = pam_get_item(idata.pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(idata.pamh, LOG_ERR, "Error recovering pam user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(idata.pamh, user_name);
+ if (!pwd) {
+ pam_syslog(idata.pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Add the user info to the instance data so we can refer to them later.
+ */
+ idata.user[0] = 0;
+ strncat(idata.user, user_name, sizeof(idata.user) - 1);
+ idata.uid = pwd->pw_uid;
+
+ /*
+ * Parse namespace configuration file which lists directories to
+ * polyinstantiate, directory where instance directories are to
+ * be created and the method used for polyinstantiation.
+ */
+ retval = parse_config_file(&idata);
+ if (retval != PAM_SUCCESS) {
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SESSION_ERR;
+ }
+
+ if (idata.polydirs_ptr) {
+ retval = setup_namespace(&idata, unmnt);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "namespace setup ok for pid %d", getpid());
+ }
+ } else if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Nothing to polyinstantiate");
+
+ del_polydir_list(idata.polydirs_ptr);
+ return retval;
+}
+
+
+/*
+ * Entry point from pam_close_session call.
+ */
+PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED,
+ int argc, const char **argv)
+{
+ int i, retval;
+ struct instance_data idata;
+ char *user_name;
+ struct passwd *pwd;
+
+ /* init instance data */
+ idata.flags = 0;
+ idata.polydirs_ptr = NULL;
+ idata.pamh = pamh;
+#ifdef WITH_SELINUX
+ if (is_selinux_enabled())
+ idata.flags |= PAMNS_SELINUX_ENABLED;
+ if (ctxt_based_inst_needed())
+ idata.flags |= PAMNS_CTXT_BASED_INST;
+#endif
+
+ /* Parse arguments. */
+ for (i = 0; i < argc; i++) {
+ if (strcmp(argv[i], "debug") == 0)
+ idata.flags |= PAMNS_DEBUG;
+ if (strcmp(argv[i], "ignore_config_error") == 0)
+ idata.flags |= PAMNS_IGN_CONFIG_ERR;
+ }
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "close_session - start");
+
+ /*
+ * Lookup user and fill struct items
+ */
+ retval = pam_get_item(idata.pamh, PAM_USER, (void*) &user_name );
+ if ( user_name == NULL || retval != PAM_SUCCESS ) {
+ pam_syslog(idata.pamh, LOG_ERR, "Error recovering pam user name");
+ return PAM_SESSION_ERR;
+ }
+
+ pwd = pam_modutil_getpwnam(idata.pamh, user_name);
+ if (!pwd) {
+ pam_syslog(idata.pamh, LOG_ERR, "user unknown '%s'", user_name);
+ return PAM_SESSION_ERR;
+ }
+
+ /*
+ * Add the user info to the instance data so we can refer to them later.
+ */
+ idata.user[0] = 0;
+ strncat(idata.user, user_name, sizeof(idata.user) - 1);
+ idata.uid = pwd->pw_uid;
+
+ /*
+ * Parse namespace configuration file which lists directories that
+ * are polyinstantiated, directories where instance directories are
+ * created and the method used for polyinstantiation.
+ */
+ retval = parse_config_file(&idata);
+ if ((retval != PAM_SUCCESS) || !idata.polydirs_ptr) {
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SESSION_ERR;
+ }
+
+ if (idata.flags & PAMNS_DEBUG)
+ pam_syslog(idata.pamh, LOG_DEBUG, "Resetting namespace for pid %d",
+ getpid());
+
+ retval = orig_namespace(&idata);
+ if (idata.flags & PAMNS_DEBUG) {
+ if (retval)
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace failed for pid %d", getpid());
+ else
+ pam_syslog(idata.pamh, LOG_DEBUG,
+ "resetting namespace ok for pid %d", getpid());
+ }
+ del_polydir_list(idata.polydirs_ptr);
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_namespace_modstruct = {
+ "pam_namespace",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL
+};
+#endif
diff --git a/Linux-PAM/modules/pam_namespace/pam_namespace.h b/Linux-PAM/modules/pam_namespace/pam_namespace.h
new file mode 100644
index 00000000..c918cff3
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/pam_namespace.h
@@ -0,0 +1,135 @@
+/******************************************************************************
+ * A module for Linux-PAM that will set the default namespace after
+ * establishing a session via PAM.
+ *
+ * (C) Copyright IBM Corporation 2005
+ * (C) Copyright Red Hat 2006
+ * All Rights Reserved.
+ *
+ * Written by: Janak Desai <janak@us.ibm.com>
+ * With Revisions by: Steve Grubb <sgrubb@redhat.com>
+ * Derived from a namespace setup patch by Chad Sellers <cdselle@tycho.nsa.gov>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#if !(defined(linux))
+#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
+#endif
+
+#include "config.h"
+
+#include <stdio.h>
+#include <stdio_ext.h>
+#include <unistd.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <syslog.h>
+#include <dlfcn.h>
+#include <stdarg.h>
+#include <pwd.h>
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
+#include <sys/mount.h>
+#include <sys/wait.h>
+#include <libgen.h>
+#include <fcntl.h>
+#include <sched.h>
+#include "security/pam_modules.h"
+#include "security/pam_modutil.h"
+#include "security/pam_ext.h"
+#include "md5.h"
+
+#ifdef WITH_SELINUX
+#include <selinux/selinux.h>
+#endif
+
+#ifndef CLONE_NEWNS
+#define CLONE_NEWNS 0x00020000 /* Flag to create new namespace */
+#endif
+
+/*
+ * Module defines
+ */
+#ifndef PAM_NAMESPACE_CONFIG
+#define PAM_NAMESPACE_CONFIG "/etc/security/namespace.conf"
+#endif
+
+#ifndef NAMESPACE_INIT_SCRIPT
+#define NAMESPACE_INIT_SCRIPT "/etc/security/namespace.init"
+#endif
+
+#define PAMNS_DEBUG 0x00000100 /* Running in debug mode */
+#define PAMNS_SELINUX_ENABLED 0x00000400 /* SELinux is enabled */
+#define PAMNS_CTXT_BASED_INST 0x00000800 /* Context based instance needed */
+#define PAMNS_GEN_HASH 0x00002000 /* Generate md5 hash for inst names */
+#define PAMNS_IGN_CONFIG_ERR 0x00004000 /* Ignore format error in conf file */
+#define PAMNS_IGN_INST_PARENT_MODE 0x00008000 /* Ignore instance parent mode */
+
+/*
+ * Polyinstantiation method options, based on user, security context
+ * or both
+ */
+enum polymethod {
+ USER,
+ CONTEXT,
+ BOTH,
+};
+
+/*
+ * Depending on the application using this namespace module, we
+ * may need to unmount priviously bind mounted instance directory.
+ * Applications such as login and sshd, that establish a new
+ * session unmount of instance directory is not needed. For applications
+ * such as su and newrole, that switch the identity, this module
+ * has to unmount previous instance directory first and re-mount
+ * based on the new indentity. For other trusted applications that
+ * just want to undo polyinstantiation, only unmount of previous
+ * instance directory is needed.
+ */
+enum unmnt_op {
+ NO_UNMNT,
+ UNMNT_REMNT,
+ UNMNT_ONLY,
+};
+
+/*
+ * Structure that holds information about a directory to polyinstantiate
+ */
+struct polydir_s {
+ char dir[PATH_MAX]; /* directory to polyinstantiate */
+ char instance_prefix[PATH_MAX]; /* prefix for instance dir path name */
+ enum polymethod method; /* method used to polyinstantiate */
+ unsigned int num_uids; /* number of override uids */
+ uid_t *uid; /* list of override uids */
+ struct polydir_s *next; /* pointer to the next polydir entry */
+};
+
+struct instance_data {
+ pam_handle_t *pamh; /* The pam handle for this instance */
+ struct polydir_s *polydirs_ptr; /* The linked list pointer */
+ char user[LOGIN_NAME_MAX]; /* User name */
+ uid_t uid; /* The uid of the user */
+ unsigned long flags; /* Flags for debug, selinux etc */
+};
diff --git a/Linux-PAM/modules/pam_namespace/tst-pam_namespace b/Linux-PAM/modules/pam_namespace/tst-pam_namespace
new file mode 100755
index 00000000..c929dfcf
--- /dev/null
+++ b/Linux-PAM/modules/pam_namespace/tst-pam_namespace
@@ -0,0 +1,2 @@
+#!/bin/sh
+../../tests/tst-dlopen .libs/pam_namespace.so