diff options
author | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 17:53:41 -0800 |
---|---|---|
committer | Steve Langasek <steve.langasek@ubuntu.com> | 2019-01-03 18:17:08 -0800 |
commit | 212b52cf29c06cc209bc8ac0540dbab1acdf1464 (patch) | |
tree | 58da0bf39f5c4122e4a1b4da20fdeea52b97a671 /modules/pam_mkhomedir | |
parent | 9c52e721044e7501c3d4567b36d222dc7326224a (diff) | |
parent | 56c8282d128fb484ffc77dff73abf42229b291d3 (diff) |
New upstream version 1.1.0
Diffstat (limited to 'modules/pam_mkhomedir')
-rw-r--r-- | modules/pam_mkhomedir/Makefile.am | 12 | ||||
-rw-r--r-- | modules/pam_mkhomedir/Makefile.in | 172 | ||||
-rw-r--r-- | modules/pam_mkhomedir/README | 2 | ||||
-rw-r--r-- | modules/pam_mkhomedir/mkhomedir_helper.8 | 203 | ||||
-rw-r--r-- | modules/pam_mkhomedir/mkhomedir_helper.8.xml | 78 | ||||
-rw-r--r-- | modules/pam_mkhomedir/mkhomedir_helper.c | 422 | ||||
-rw-r--r-- | modules/pam_mkhomedir/pam_mkhomedir.8 | 254 | ||||
-rw-r--r-- | modules/pam_mkhomedir/pam_mkhomedir.8.xml | 10 | ||||
-rw-r--r-- | modules/pam_mkhomedir/pam_mkhomedir.c | 455 |
9 files changed, 1152 insertions, 456 deletions
diff --git a/modules/pam_mkhomedir/Makefile.am b/modules/pam_mkhomedir/Makefile.am index 7ed3a9f0..42031472 100644 --- a/modules/pam_mkhomedir/Makefile.am +++ b/modules/pam_mkhomedir/Makefile.am @@ -1,21 +1,23 @@ # # Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> +# Copyright (c) 2008 Red Hat, Inc. # CLEANFILES = *~ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_mkhomedir -man_MANS = pam_mkhomedir.8 +man_MANS = pam_mkhomedir.8 mkhomedir_helper.8 -XMLS = README.xml pam_mkhomedir.8.xml +XMLS = README.xml pam_mkhomedir.8.xml mkhomedir_helper.8.xml TESTS = tst-pam_mkhomedir securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ + -DMKHOMEDIR_HELPER=\"$(sbindir)/mkhomedir_helper\" AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map @@ -25,6 +27,10 @@ securelib_LTLIBRARIES = pam_mkhomedir.la pam_mkhomedir_la_SOURCES = pam_mkhomedir.c pam_mkhomedir_la_LIBADD = -L$(top_builddir)/libpam -lpam +sbin_PROGRAMS = mkhomedir_helper +mkhomedir_helper_SOURCES = mkhomedir_helper.c +mkhomedir_helper_LDADD = -L$(top_builddir)/libpam -lpam + if ENABLE_REGENERATE_MAN noinst_DATA = README README: pam_mkhomedir.8.xml diff --git a/modules/pam_mkhomedir/Makefile.in b/modules/pam_mkhomedir/Makefile.in index 24cb3b73..306ec12d 100644 --- a/modules/pam_mkhomedir/Makefile.in +++ b/modules/pam_mkhomedir/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -16,9 +16,11 @@ # # Copyright (c) 2005, 2006 Thorsten Kukuk <kukuk@suse.de> +# Copyright (c) 2008 Red Hat, Inc. # + VPATH = @srcdir@ pkgdatadir = $(datadir)/@PACKAGE@ pkglibdir = $(libdir)/@PACKAGE@ @@ -38,17 +40,21 @@ POST_UNINSTALL = : build_triplet = @build@ host_triplet = @host@ @HAVE_VERSIONING_TRUE@am__append_1 = -Wl,--version-script=$(srcdir)/../modules.map +sbin_PROGRAMS = mkhomedir_helper$(EXEEXT) subdir = modules/pam_mkhomedir DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/japhar_grep_cflags.m4 \ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) @@ -61,12 +67,18 @@ am__vpath_adj = case $$p in \ *) f=$$p;; \ esac; am__strip_dir = `echo $$p | sed -e 's|^.*/||'`; -am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)" +am__installdirs = "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" \ + "$(DESTDIR)$(man8dir)" securelibLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(securelib_LTLIBRARIES) pam_mkhomedir_la_DEPENDENCIES = am_pam_mkhomedir_la_OBJECTS = pam_mkhomedir.lo pam_mkhomedir_la_OBJECTS = $(am_pam_mkhomedir_la_OBJECTS) +sbinPROGRAMS_INSTALL = $(INSTALL_PROGRAM) +PROGRAMS = $(sbin_PROGRAMS) +am_mkhomedir_helper_OBJECTS = mkhomedir_helper.$(OBJEXT) +mkhomedir_helper_OBJECTS = $(am_mkhomedir_helper_OBJECTS) +mkhomedir_helper_DEPENDENCIES = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/depcomp am__depfiles_maybe = depfiles @@ -79,8 +91,8 @@ CCLD = $(CC) LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ $(LDFLAGS) -o $@ -SOURCES = $(pam_mkhomedir_la_SOURCES) -DIST_SOURCES = $(pam_mkhomedir_la_SOURCES) +SOURCES = $(pam_mkhomedir_la_SOURCES) $(mkhomedir_helper_SOURCES) +DIST_SOURCES = $(pam_mkhomedir_la_SOURCES) $(mkhomedir_helper_SOURCES) man8dir = $(mandir)/man8 NROFF = nroff MANS = $(man_MANS) @@ -101,23 +113,19 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ -ECHO = @ECHO@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ +FGREP = @FGREP@ FO2PDF = @FO2PDF@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ @@ -129,6 +137,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ @@ -152,6 +161,7 @@ LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@ LIBS = @LIBS@ LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ @@ -161,15 +171,18 @@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NM = @NM@ NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ -PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ @@ -183,10 +196,9 @@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ -WITH_DEBUG = @WITH_DEBUG@ -WITH_PAMLOCKING = @WITH_PAMLOCKING@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ XMLCATALOG = @XMLCATALOG@ XMLLINT = @XMLLINT@ XML_CATALOG_FILE = @XML_CATALOG_FILE@ @@ -198,8 +210,7 @@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -231,6 +242,7 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -245,20 +257,25 @@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *~ EXTRA_DIST = README $(MANS) $(XMLS) tst-pam_mkhomedir -man_MANS = pam_mkhomedir.8 -XMLS = README.xml pam_mkhomedir.8.xml +man_MANS = pam_mkhomedir.8 mkhomedir_helper.8 +XMLS = README.xml pam_mkhomedir.8.xml mkhomedir_helper.8.xml TESTS = tst-pam_mkhomedir securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) -AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include +AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ + -DMKHOMEDIR_HELPER=\"$(sbindir)/mkhomedir_helper\" + AM_LDFLAGS = -no-undefined -avoid-version -module $(am__append_1) securelib_LTLIBRARIES = pam_mkhomedir.la pam_mkhomedir_la_SOURCES = pam_mkhomedir.c pam_mkhomedir_la_LIBADD = -L$(top_builddir)/libpam -lpam +mkhomedir_helper_SOURCES = mkhomedir_helper.c +mkhomedir_helper_LDADD = -L$(top_builddir)/libpam -lpam @ENABLE_REGENERATE_MAN_TRUE@noinst_DATA = README all: all-am @@ -268,8 +285,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ @@ -322,6 +339,37 @@ clean-securelibLTLIBRARIES: done pam_mkhomedir.la: $(pam_mkhomedir_la_OBJECTS) $(pam_mkhomedir_la_DEPENDENCIES) $(LINK) -rpath $(securelibdir) $(pam_mkhomedir_la_OBJECTS) $(pam_mkhomedir_la_LIBADD) $(LIBS) +install-sbinPROGRAMS: $(sbin_PROGRAMS) + @$(NORMAL_INSTALL) + test -z "$(sbindir)" || $(MKDIR_P) "$(DESTDIR)$(sbindir)" + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + p1=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + if test -f $$p \ + || test -f $$p1 \ + ; then \ + f=`echo "$$p1" | sed 's,^.*/,,;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) '$$p' '$(DESTDIR)$(sbindir)/$$f'"; \ + $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(sbinPROGRAMS_INSTALL) "$$p" "$(DESTDIR)$(sbindir)/$$f" || exit 1; \ + else :; fi; \ + done + +uninstall-sbinPROGRAMS: + @$(NORMAL_UNINSTALL) + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f=`echo "$$p" | sed 's,^.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/'`; \ + echo " rm -f '$(DESTDIR)$(sbindir)/$$f'"; \ + rm -f "$(DESTDIR)$(sbindir)/$$f"; \ + done + +clean-sbinPROGRAMS: + @list='$(sbin_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +mkhomedir_helper$(EXEEXT): $(mkhomedir_helper_OBJECTS) $(mkhomedir_helper_DEPENDENCIES) + @rm -f mkhomedir_helper$(EXEEXT) + $(LINK) $(mkhomedir_helper_OBJECTS) $(mkhomedir_helper_LDADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -329,6 +377,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mkhomedir_helper.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pam_mkhomedir.Plo@am__quote@ .c.o: @@ -368,8 +417,8 @@ install-man8: $(man8_MANS) $(man_MANS) esac; \ done; \ for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ + if test -f $$i; then file=$$i; \ + else file=$(srcdir)/$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ @@ -408,7 +457,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -451,7 +500,7 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ if test -n "$$list"; then \ @@ -462,7 +511,7 @@ check-TESTS: $(TESTS) if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ @@ -474,7 +523,7 @@ check-TESTS: $(TESTS) elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ @@ -488,23 +537,36 @@ check-TESTS: $(TESTS) echo "SKIP: $$tst"; \ fi; \ done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ + banner="$$All$$all $$tests passed"; \ else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ + banner="$$failed of $$all $$tests failed"; \ else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ - skipped="($$skip tests were not run)"; \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ @@ -552,9 +614,9 @@ distdir: $(DISTFILES) check-am: all-am $(MAKE) $(AM_MAKEFLAGS) check-TESTS check: check-am -all-am: Makefile $(LTLIBRARIES) $(MANS) $(DATA) +all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(MANS) $(DATA) installdirs: - for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(man8dir)"; do \ + for dir in "$(DESTDIR)$(securelibdir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(man8dir)"; do \ test -z "$$dir" || $(MKDIR_P) "$$dir"; \ done install: install-am @@ -584,8 +646,8 @@ maintainer-clean-generic: @echo "it deletes files that may require special tools to rebuild." clean: clean-am -clean-am: clean-generic clean-libtool clean-securelibLTLIBRARIES \ - mostlyclean-am +clean-am: clean-generic clean-libtool clean-sbinPROGRAMS \ + clean-securelibLTLIBRARIES mostlyclean-am distclean: distclean-am -rm -rf ./$(DEPDIR) @@ -607,7 +669,7 @@ install-data-am: install-man install-securelibLTLIBRARIES install-dvi: install-dvi-am -install-exec-am: +install-exec-am: install-sbinPROGRAMS install-html: install-html-am @@ -639,26 +701,28 @@ ps: ps-am ps-am: -uninstall-am: uninstall-man uninstall-securelibLTLIBRARIES +uninstall-am: uninstall-man uninstall-sbinPROGRAMS \ + uninstall-securelibLTLIBRARIES uninstall-man: 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-man8 install-pdf \ - install-pdf-am install-ps install-ps-am \ - 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-man8 \ + clean-generic clean-libtool clean-sbinPROGRAMS \ + 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-man8 \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-sbinPROGRAMS 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-man8 uninstall-sbinPROGRAMS \ uninstall-securelibLTLIBRARIES @ENABLE_REGENERATE_MAN_TRUE@README: pam_mkhomedir.8.xml diff --git a/modules/pam_mkhomedir/README b/modules/pam_mkhomedir/README index 64810060..cfc7bc48 100644 --- a/modules/pam_mkhomedir/README +++ b/modules/pam_mkhomedir/README @@ -8,7 +8,7 @@ The pam_mkhomedir PAM module will create a users home directory if it does not exist when the session begins. This allows users to be present in central database (such as NIS, kerberos or LDAP) without using a distributed file system or pre-creating a large number of directories. The skeleton directory -(usually /etc/skel/) is used to copy default files and also set's a umask for +(usually /etc/skel/) is used to copy default files and also sets a umask for the creation. The new users home directory will not be removed after logout of the user. diff --git a/modules/pam_mkhomedir/mkhomedir_helper.8 b/modules/pam_mkhomedir/mkhomedir_helper.8 new file mode 100644 index 00000000..75dfa56e --- /dev/null +++ b/modules/pam_mkhomedir/mkhomedir_helper.8 @@ -0,0 +1,203 @@ +.\" Title: mkhomedir_helper +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/> +.\" Date: 03/02/2009 +.\" Manual: Linux-PAM Manual +.\" Source: Linux-PAM Manual +.\" Language: English +.\" +.TH "MKHOMEDIR_HELPER" "8" "03/02/2009" "Linux-PAM Manual" "Linux\-PAM Manual" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- +.\" disable hyphenation +.nh +.\" disable justification (adjust text to left margin only) +.ad l +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +mkhomedir_helper \- Helper binary that creates home directories +.SH "Synopsis" +.fam C +.HP \w'\fBmkhomedir_helper\fR\ 'u +\fBmkhomedir_helper\fR {\fIuser\fR} [\fIumask\fR\ [\ \fIpath\-to\-skel\fR\ ]] +.fam +.SH "DESCRIPTION" +.PP + +\fImkhomedir_helper\fR +is a helper program for the +\fIpam_mkhomedir\fR +module that creates home directories and populates them with contents of the specified skel directory\&. +.PP +The default value of +\fIumask\fR +is 0022 and the default value of +\fIpath\-to\-skel\fR +is +\fI/etc/skel\fR\&. +.PP +The helper is separated from the module to not require direct access from login SELinux domains to the contents of user home directories\&. The SELinux domain transition happens when the module is executing the +\fImkhomedir_helper\fR\&. +.PP +The helper never touches home directories if they already exist\&. +.SH "SEE ALSO" +.PP + +\fBpam_mkhomedir\fR(8) +.SH "AUTHOR" +.PP +Written by Tomas Mraz based on the code originally in +\fIpam_mkhomedir\fR +module\&. diff --git a/modules/pam_mkhomedir/mkhomedir_helper.8.xml b/modules/pam_mkhomedir/mkhomedir_helper.8.xml new file mode 100644 index 00000000..c834eddd --- /dev/null +++ b/modules/pam_mkhomedir/mkhomedir_helper.8.xml @@ -0,0 +1,78 @@ +<?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="mkhomedir_helper"> + + <refmeta> + <refentrytitle>mkhomedir_helper</refentrytitle> + <manvolnum>8</manvolnum> + <refmiscinfo class="sectdesc">Linux-PAM Manual</refmiscinfo> + </refmeta> + + <refnamediv id="mkhomedir_helper-name"> + <refname>mkhomedir_helper</refname> + <refpurpose>Helper binary that creates home directories</refpurpose> + </refnamediv> + + <refsynopsisdiv> + <cmdsynopsis id="mkhomedir_helper-cmdsynopsis"> + <command>mkhomedir_helper</command> + <arg choice="req"> + <replaceable>user</replaceable> + </arg> + <arg choice="opt"> + <replaceable>umask</replaceable> + <arg choice="opt"> + <replaceable>path-to-skel</replaceable> + </arg> + </arg> + </cmdsynopsis> + </refsynopsisdiv> + + <refsect1 id="mkhomedir_helper-description"> + + <title>DESCRIPTION</title> + + <para> + <emphasis>mkhomedir_helper</emphasis> is a helper program for the + <emphasis>pam_mkhomedir</emphasis> module that creates home directories + and populates them with contents of the specified skel directory. + </para> + + <para> + The default value of <replaceable>umask</replaceable> is 0022 and the + default value of <replaceable>path-to-skel</replaceable> is + <emphasis>/etc/skel</emphasis>. + </para> + + <para> + The helper is separated from the module to not require direct access from + login SELinux domains to the contents of user home directories. The + SELinux domain transition happens when the module is executing the + <emphasis>mkhomedir_helper</emphasis>. + </para> + + <para> + The helper never touches home directories if they already exist. + </para> + </refsect1> + + <refsect1 id='mkhomedir_helper-see_also'> + <title>SEE ALSO</title> + <para> + <citerefentry> + <refentrytitle>pam_mkhomedir</refentrytitle><manvolnum>8</manvolnum> + </citerefentry> + </para> + </refsect1> + + <refsect1 id='mkhomedir_helper-author'> + <title>AUTHOR</title> + <para> + Written by Tomas Mraz based on the code originally in + <emphasis>pam_mkhomedir</emphasis> module. + </para> + </refsect1> + +</refentry> diff --git a/modules/pam_mkhomedir/mkhomedir_helper.c b/modules/pam_mkhomedir/mkhomedir_helper.c new file mode 100644 index 00000000..550a1354 --- /dev/null +++ b/modules/pam_mkhomedir/mkhomedir_helper.c @@ -0,0 +1,422 @@ +/* mkhomedir_helper - helper for pam_mkhomedir module + + Released under the GNU LGPL version 2 or later + + Copyright (c) Red Hat, Inc., 2009 + Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999 + Structure taken from pam_lastlogin by Andrew Morgan + <morgan@parc.power.net> 1996 + */ + +#include "config.h" + +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <pwd.h> +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <dirent.h> +#include <syslog.h> + +#include <security/pam_ext.h> +#include <security/pam_modutil.h> + +static unsigned long u_mask = 0022; +static char skeldir[BUFSIZ] = "/etc/skel"; + +static int +rec_mkdir(const char *dir, mode_t mode) +{ + char *cp; + char *parent = strdup(dir); + + if (parent == NULL) + return 1; + + cp = strrchr(parent, '/'); + + if (cp != NULL && cp != parent) + { + struct stat st; + + *cp++ = '\0'; + if (stat(parent, &st) == -1 && errno == ENOENT) + if (rec_mkdir(parent, mode) != 0) + { + free(parent); + return 1; + } + } + + free(parent); + + if (mkdir(dir, mode) != 0 && errno != EEXIST) + return 1; + + return 0; +} + +/* Do the actual work of creating a home dir */ +static int +create_homedir(const struct passwd *pwd, + const char *source, const char *dest) +{ + char remark[BUFSIZ]; + DIR *d; + struct dirent *dent; + int retval = PAM_SESSION_ERR; + + /* Create the new directory */ + if (rec_mkdir(dest, 0755) != 0) + { + pam_syslog(NULL, LOG_ERR, "unable to create directory %s: %m", dest); + return PAM_PERM_DENIED; + } + + /* See if we need to copy the skel dir over. */ + if ((source == NULL) || (strlen(source) == 0)) + { + retval = PAM_SUCCESS; + goto go_out; + } + + /* Scan the directory */ + d = opendir(source); + if (d == NULL) + { + pam_syslog(NULL, LOG_DEBUG, "unable to read directory %s: %m", source); + retval = PAM_PERM_DENIED; + goto go_out; + } + + for (dent = readdir(d); dent != NULL; dent = readdir(d)) + { + int srcfd; + int destfd; + int res; + struct stat st; +#ifndef PATH_MAX + char *newsource = NULL, *newdest = NULL; + /* track length of buffers */ + int nslen = 0, ndlen = 0; + int slen = strlen(source), dlen = strlen(dest); +#else + char newsource[PATH_MAX], newdest[PATH_MAX]; +#endif + + /* Skip some files.. */ + if (strcmp(dent->d_name,".") == 0 || + strcmp(dent->d_name,"..") == 0) + continue; + + /* Determine what kind of file it is. */ +#ifndef PATH_MAX + nslen = slen + strlen(dent->d_name) + 2; + + if (nslen <= 0) + { + retval = PAM_BUF_ERR; + goto go_out; + } + + if ((newsource = malloc(nslen)) == NULL) + { + retval = PAM_BUF_ERR; + goto go_out; + } + + sprintf(newsource, "%s/%s", source, dent->d_name); +#else + snprintf(newsource, sizeof(newsource), "%s/%s", source, dent->d_name); +#endif + + if (lstat(newsource, &st) != 0) +#ifndef PATH_MAX + { + free(newsource); + newsource = NULL; + continue; + } +#else + continue; +#endif + + + /* We'll need the new file's name. */ +#ifndef PATH_MAX + ndlen = dlen + strlen(dent->d_name)+2; + + if (ndlen <= 0) + { + retval = PAM_BUF_ERR; + goto go_out; + } + + if ((newdest = malloc(ndlen)) == NULL) + { + free (newsource); + retval = PAM_BUF_ERR; + goto go_out; + } + + sprintf (newdest, "%s/%s", dest, dent->d_name); +#else + snprintf (newdest, sizeof (newdest), "%s/%s", dest, dent->d_name); +#endif + + /* If it's a directory, recurse. */ + if (S_ISDIR(st.st_mode)) + { + retval = create_homedir(pwd, newsource, newdest); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + if (retval != PAM_SUCCESS) + { + closedir(d); + goto go_out; + } + continue; + } + + /* If it's a symlink, create a new link. */ + if (S_ISLNK(st.st_mode)) + { + int pointedlen = 0; +#ifndef PATH_MAX + char *pointed = NULL; + { + int size = 100; + + while (1) { + pointed = malloc(size); + if (pointed == NULL) { + free(newsource); + free(newdest); + return PAM_BUF_ERR; + } + pointedlen = readlink(newsource, pointed, size); + if (pointedlen < 0) break; + if (pointedlen < size) break; + free(pointed); + size *= 2; + } + } + if (pointedlen < 0) + free(pointed); + else + pointed[pointedlen] = 0; +#else + char pointed[PATH_MAX]; + memset(pointed, 0, sizeof(pointed)); + + pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); +#endif + + if (pointedlen >= 0) { + if(symlink(pointed, newdest) == 0) + { + if (lchown(newdest, pwd->pw_uid, pwd->pw_gid) != 0) + { + pam_syslog(NULL, LOG_DEBUG, + "unable to change perms on link %s: %m", newdest); + closedir(d); +#ifndef PATH_MAX + free(pointed); + free(newsource); + free(newdest); +#endif + return PAM_PERM_DENIED; + } + } +#ifndef PATH_MAX + free(pointed); +#endif + } +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + continue; + } + + /* If it's not a regular file, it's probably not a good idea to create + * the new device node, FIFO, or whatever it is. */ + if (!S_ISREG(st.st_mode)) + { +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + continue; + } + + /* Open the source file */ + if ((srcfd = open(newsource, O_RDONLY)) < 0 || fstat(srcfd, &st) != 0) + { + pam_syslog(NULL, LOG_DEBUG, + "unable to open src file %s: %m", newsource); + closedir(d); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + return PAM_PERM_DENIED; + } + if (stat(newsource, &st) != 0) + { + pam_syslog(NULL, LOG_DEBUG, "unable to stat src file %s: %m", + newsource); + close(srcfd); + closedir(d); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + return PAM_PERM_DENIED; + } + + /* Open the dest file */ + if ((destfd = open(newdest, O_WRONLY | O_TRUNC | O_CREAT, 0600)) < 0) + { + pam_syslog(NULL, LOG_DEBUG, + "unable to open dest file %s: %m", newdest); + close(srcfd); + closedir(d); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + return PAM_PERM_DENIED; + } + + /* Set the proper ownership and permissions for the module. We make + the file a+w and then mask it with the set mask. This preseves + execute bits */ + if (fchmod(destfd, (st.st_mode | 0222) & (~u_mask)) != 0 || + fchown(destfd, pwd->pw_uid, pwd->pw_gid) != 0) + { + pam_syslog(NULL, LOG_DEBUG, + "unable to change perms on copy %s: %m", newdest); + close(srcfd); + close(destfd); + closedir(d); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + return PAM_PERM_DENIED; + } + + /* Copy the file */ + do + { + res = pam_modutil_read(srcfd, remark, sizeof(remark)); + + if (res == 0) + continue; + + if (res > 0) { + if (pam_modutil_write(destfd, remark, res) == res) + continue; + } + + /* If we get here, pam_modutil_read returned a -1 or + pam_modutil_write returned something unexpected. */ + pam_syslog(NULL, LOG_DEBUG, "unable to perform IO: %m"); + close(srcfd); + close(destfd); + closedir(d); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + return PAM_PERM_DENIED; + } + while (res != 0); + close(srcfd); + close(destfd); + +#ifndef PATH_MAX + free(newsource); newsource = NULL; + free(newdest); newdest = NULL; +#endif + + } + closedir(d); + + retval = PAM_SUCCESS; + + go_out: + + if (chmod(dest, 0777 & (~u_mask)) != 0 || + chown(dest, pwd->pw_uid, pwd->pw_gid) != 0) + { + pam_syslog(NULL, LOG_DEBUG, + "unable to change perms on directory %s: %m", dest); + return PAM_PERM_DENIED; + } + + return retval; +} + +int +main(int argc, char *argv[]) +{ + const struct passwd *pwd; + struct stat st; + + if (argc < 2) { + fprintf(stderr, "Usage: %s <username> [<umask> [<skeldir>]]\n", argv[0]); + return PAM_SESSION_ERR; + } + + pwd = getpwnam(argv[1]); + if (pwd == NULL) { + pam_syslog(NULL, LOG_ERR, "User unknown."); + return PAM_CRED_INSUFFICIENT; + } + + if (argc >= 3) { + char *eptr; + errno = 0; + u_mask = strtoul(argv[2], &eptr, 0); + if (errno != 0 || *eptr != '\0') { + pam_syslog(NULL, LOG_ERR, "Bogus umask value %s", argv[2]); + return PAM_SESSION_ERR; + } + } + + if (argc >= 4) { + if (strlen(argv[3]) >= sizeof(skeldir)) { + pam_syslog(NULL, LOG_ERR, "Too long skeldir path."); + return PAM_SESSION_ERR; + } + strcpy(skeldir, argv[3]); + } + + /* Stat the home directory, if something exists then we assume it is + correct and return a success */ + if (stat(pwd->pw_dir, &st) == 0) + return PAM_SUCCESS; + + return create_homedir(pwd, skeldir, pwd->pw_dir); +} + diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8 b/modules/pam_mkhomedir/pam_mkhomedir.8 index cab1fda1..719ff90f 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.8 +++ b/modules/pam_mkhomedir/pam_mkhomedir.8 @@ -1,109 +1,285 @@ .\" Title: pam_mkhomedir -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/> -.\" Date: 04/16/2008 +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/> +.\" Date: 06/16/2009 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual +.\" Language: English .\" -.TH "PAM_MKHOMEDIR" "8" "04/16/2008" "Linux-PAM Manual" "Linux-PAM Manual" +.TH "PAM_MKHOMEDIR" "8" "06/16/2009" "Linux-PAM Manual" "Linux-PAM Manual" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l -.SH "NAME" -pam_mkhomedir - PAM module to create users home directory -.SH "SYNOPSIS" -.HP 17 -\fBpam_mkhomedir\.so\fR [silent] [umask=\fImode\fR] [skel=\fIskeldir\fR] +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +pam_mkhomedir \- PAM module to create users home directory +.SH "Synopsis" +.fam C +.HP \w'\fBpam_mkhomedir\&.so\fR\ 'u +\fBpam_mkhomedir\&.so\fR [silent] [umask=\fImode\fR] [skel=\fIskeldir\fR] +.fam .SH "DESCRIPTION" .PP -The pam_mkhomedir PAM module will create a users home directory if it does not exist when the session begins\. This allows users to be present in central database (such as NIS, kerberos or LDAP) without using a distributed file system or pre\-creating a large number of directories\. The skeleton directory (usually -\fI/etc/skel/\fR) is used to copy default files and also set\'s a umask for the creation\. +The pam_mkhomedir PAM module will create a users home directory if it does not exist when the session begins\&. This allows users to be present in central database (such as NIS, kerberos or LDAP) without using a distributed file system or pre\-creating a large number of directories\&. The skeleton directory (usually +\FC/etc/skel/\F[]) is used to copy default files and also sets a umask for the creation\&. .PP -The new users home directory will not be removed after logout of the user\. +The new users home directory will not be removed after logout of the user\&. .SH "OPTIONS" .PP \fBsilent\fR .RS 4 -Don\'t print informative messages\. +Don\'t print informative messages\&. .RE .PP \fBumask=\fR\fB\fImask\fR\fR .RS 4 The user file\-creation mask is set to -\fImask\fR\. The default value of mask is 0022\. +\fImask\fR\&. The default value of mask is 0022\&. .RE .PP \fBskel=\fR\fB\fI/path/to/skel/directory\fR\fR .RS 4 Indicate an alternative -\fIskel\fR +\FCskel\F[] directory to override the default -\fI/etc/skel\fR\. +\FC/etc/skel\F[]\&. .RE -.SH "MODULE SERVICES PROVIDED" +.SH "MODULE TYPES PROVIDED" .PP Only the \fBsession\fR -service is supported\. +module type is provided\&. .SH "RETURN VALUES" .PP PAM_BUF_ERR .RS 4 -Memory buffer error\. +Memory buffer error\&. .RE .PP PAM_CRED_INSUFFICIENT .RS 4 -Insufficient credentials to access authentication data\. +Insufficient credentials to access authentication data\&. .RE .PP PAM_PERM_DENIED .RS 4 -Not enough permissions to create the new directory or read the skel directory\. +Not enough permissions to create the new directory or read the skel directory\&. .RE .PP PAM_USER_UNKNOWN .RS 4 -User not known to the underlying authentication module\. +User not known to the underlying authentication module\&. .RE .PP PAM_SUCCESS .RS 4 -Environment variables were set\. +Environment variables were set\&. .RE .SH "FILES" .PP -\fI/etc/skel\fR +\FC/etc/skel\F[] .RS 4 Default skel directory .RE .SH "EXAMPLES" .PP -A sample /etc/pam\.d/login file: +A sample /etc/pam\&.d/login file: .sp +.if n \{\ .RS 4 +.\} +.fam C +.ps -1 .nf - auth requisite pam_securetty\.so - auth sufficient pam_ldap\.so - auth required pam_unix\.so - auth required pam_nologin\.so - account sufficient pam_ldap\.so - account required pam_unix\.so - password required pam_unix\.so - session required pam_mkhomedir\.so skel=/etc/skel/ umask=0022 - session required pam_unix\.so - session optional pam_lastlog\.so - session optional pam_mail\.so standard +.if t \{\ +.sp -1 +.\} +.BB lightgray adjust-for-leading-newline +.sp -1 + + auth requisite pam_securetty\&.so + auth sufficient pam_ldap\&.so + auth required pam_unix\&.so + auth required pam_nologin\&.so + account sufficient pam_ldap\&.so + account required pam_unix\&.so + password required pam_unix\&.so + session required pam_mkhomedir\&.so skel=/etc/skel/ umask=0022 + session required pam_unix\&.so + session optional pam_lastlog\&.so + session optional pam_mail\&.so standard +.EB lightgray adjust-for-leading-newline +.if t \{\ +.sp 1 +.\} .fi +.fam +.ps +1 +.if n \{\ .RE +.\} .sp .SH "SEE ALSO" .PP -\fBpam.d\fR(8), -\fBpam\fR(8)\. +\fBpam.d\fR(5), +\fBpam\fR(8)\&. .SH "AUTHOR" .PP -pam_mkhomedir was written by Jason Gunthorpe <jgg@debian\.org>\. +pam_mkhomedir was written by Jason Gunthorpe <jgg@debian\&.org>\&. diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8.xml b/modules/pam_mkhomedir/pam_mkhomedir.8.xml index 3c40de15..c980ce1d 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.8.xml +++ b/modules/pam_mkhomedir/pam_mkhomedir.8.xml @@ -44,7 +44,7 @@ without using a distributed file system or pre-creating a large number of directories. The skeleton directory (usually <filename>/etc/skel/</filename>) is used to copy default files - and also set's a umask for the creation. + and also sets a umask for the creation. </para> <para> The new users home directory will not be removed after logout @@ -95,10 +95,10 @@ </variablelist> </refsect1> - <refsect1 id="pam_mkhomedir-services"> - <title>MODULE SERVICES PROVIDED</title> + <refsect1 id="pam_mkhomedir-types"> + <title>MODULE TYPES PROVIDED</title> <para> - Only the <option>session</option> service is supported. + Only the <option>session</option> module type is provided. </para> </refsect1> @@ -186,7 +186,7 @@ <title>SEE ALSO</title> <para> <citerefentry> - <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum> + <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum> </citerefentry>, <citerefentry> <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c index 44b092c1..dfc4979e 100644 --- a/modules/pam_mkhomedir/pam_mkhomedir.c +++ b/modules/pam_mkhomedir/pam_mkhomedir.c @@ -22,6 +22,7 @@ password required pam_unix.so Released under the GNU LGPL version 2 or later + Copyright (c) Red Hat, Inc. 2009 Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999 Structure taken from pam_lastlogin by Andrew Morgan <morgan@parc.power.net> 1996 @@ -29,18 +30,19 @@ #include "config.h" -#include <stdarg.h> #include <sys/types.h> #include <sys/stat.h> -#include <fcntl.h> +#include <sys/time.h> +#include <sys/resource.h> +#include <sys/wait.h> #include <unistd.h> #include <pwd.h> #include <errno.h> #include <stdlib.h> #include <stdio.h> #include <string.h> -#include <dirent.h> #include <syslog.h> +#include <signal.h> /* * here, we make a definition for the externally accessible function @@ -56,395 +58,133 @@ #include <security/pam_modutil.h> #include <security/pam_ext.h> +#define MAX_FD_NO 10000 /* argument parsing */ #define MKHOMEDIR_DEBUG 020 /* be verbose about things */ #define MKHOMEDIR_QUIET 040 /* keep quiet about things */ -static unsigned int UMask = 0022; -static char SkelDir[BUFSIZ] = "/etc/skel"; /* THIS MODULE IS NOT THREAD SAFE */ +struct options_t { + int ctrl; + const char *umask; + const char *skeldir; +}; +typedef struct options_t options_t; -static int -_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv) +static void +_pam_parse (const pam_handle_t *pamh, int flags, int argc, const char **argv, + options_t *opt) { - int ctrl = 0; + opt->ctrl = 0; + opt->umask = "0022"; + opt->skeldir = "/etc/skel"; /* does the appliction require quiet? */ if ((flags & PAM_SILENT) == PAM_SILENT) - ctrl |= MKHOMEDIR_QUIET; + opt->ctrl |= MKHOMEDIR_QUIET; /* step through arguments */ for (; argc-- > 0; ++argv) { if (!strcmp(*argv, "silent")) { - ctrl |= MKHOMEDIR_QUIET; + opt->ctrl |= MKHOMEDIR_QUIET; } else if (!strcmp(*argv, "debug")) { - ctrl |= MKHOMEDIR_DEBUG; + opt->ctrl |= MKHOMEDIR_DEBUG; } else if (!strncmp(*argv,"umask=",6)) { - UMask = strtol(*argv+6,0,0); + opt->umask = *argv+6; } else if (!strncmp(*argv,"skel=",5)) { - strncpy(SkelDir,*argv+5,sizeof(SkelDir)); - SkelDir[sizeof(SkelDir)-1] = '\0'; + opt->skeldir = *argv+5; } else { pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv); } } - - D(("ctrl = %o", ctrl)); - return ctrl; -} - -static int -rec_mkdir (const char *dir, mode_t mode) -{ - char *cp; - char *parent = strdup (dir); - - if (parent == NULL) - return 1; - - cp = strrchr (parent, '/'); - - if (cp != NULL && cp != parent) - { - struct stat st; - - *cp++ = '\0'; - if (stat (parent, &st) == -1 && errno == ENOENT) - if (rec_mkdir (parent, mode) != 0) - { - free (parent); - return 1; - } - } - - free (parent); - - if (mkdir (dir, mode) != 0 && errno != EEXIST) - return 1; - - return 0; } /* Do the actual work of creating a home dir */ static int -create_homedir (pam_handle_t * pamh, int ctrl, - const struct passwd *pwd, - const char *source, const char *dest) +create_homedir (pam_handle_t *pamh, options_t *opt, + const struct passwd *pwd) { - char remark[BUFSIZ]; - DIR *D; - struct dirent *Dir; - int retval = PAM_AUTH_ERR; + int retval, child; + struct sigaction newsa, oldsa; /* Mention what is happening, if the notification fails that is OK */ - if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET) - pam_info(pamh, _("Creating directory '%s'."), dest); + if (!(opt->ctrl & MKHOMEDIR_QUIET)) + pam_info(pamh, _("Creating directory '%s'."), pwd->pw_dir); - /* Create the new directory */ - if (rec_mkdir (dest,0755) != 0) - { - pam_error(pamh, _("Unable to create directory %s: %m"), dest); - pam_syslog(pamh, LOG_ERR, "unable to create directory %s: %m", dest); - return PAM_PERM_DENIED; - } - /* See if we need to copy the skel dir over. */ - if ((source == NULL) || (strlen(source) == 0)) - { - retval = PAM_SUCCESS; - goto go_out; - } + D(("called.")); - /* Scan the directory */ - D = opendir (source); - if (D == 0) - { - pam_syslog(pamh, LOG_DEBUG, "unable to read directory %s: %m", source); - retval = PAM_PERM_DENIED; - goto go_out; - } + /* + * This code arranges that the demise of the child does not cause + * the application to receive a signal it is not expecting - which + * may kill the application or worse. + */ + memset(&newsa, '\0', sizeof(newsa)); + newsa.sa_handler = SIG_DFL; + sigaction(SIGCHLD, &newsa, &oldsa); - for (Dir = readdir(D); Dir != 0; Dir = readdir(D)) - { - int SrcFd; - int DestFd; - int Res; - struct stat St; -#ifndef PATH_MAX - char *newsource = NULL, *newdest = NULL; - /* track length of buffers */ - int nslen = 0, ndlen = 0; - int slen = strlen(source), dlen = strlen(dest); -#else - char newsource[PATH_MAX], newdest[PATH_MAX]; -#endif - - /* Skip some files.. */ - if (strcmp(Dir->d_name,".") == 0 || - strcmp(Dir->d_name,"..") == 0) - continue; - - /* Determine what kind of file it is. */ -#ifndef PATH_MAX - nslen = slen + strlen(Dir->d_name) + 2; - - if (nslen <= 0) - { - retval = PAM_BUF_ERR; - goto go_out; - } - - if ((newsource = malloc (nslen)) == NULL) - { - retval = PAM_BUF_ERR; - goto go_out; - } - - sprintf(newsource, "%s/%s", source, Dir->d_name); -#else - snprintf(newsource,sizeof(newsource),"%s/%s",source,Dir->d_name); -#endif - - if (lstat(newsource,&St) != 0) -#ifndef PATH_MAX - { - free(newsource); - newsource = NULL; - continue; - } -#else - continue; -#endif - - - /* We'll need the new file's name. */ -#ifndef PATH_MAX - ndlen = dlen + strlen(Dir->d_name)+2; + if (opt->ctrl & MKHOMEDIR_DEBUG) { + pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); + } - if (ndlen <= 0) - { - retval = PAM_BUF_ERR; - goto go_out; + /* fork */ + child = fork(); + if (child == 0) { + int i; + struct rlimit rlim; + static char *envp[] = { NULL }; + char *args[] = { NULL, NULL, NULL, NULL, NULL }; + + if (getrlimit(RLIMIT_NOFILE, &rlim)==0) { + if (rlim.rlim_max >= MAX_FD_NO) + rlim.rlim_max = MAX_FD_NO; + for (i=0; i < (int)rlim.rlim_max; i++) { + close(i); + } } - if ((newdest = malloc(ndlen)) == NULL) - { - free (newsource); - retval = PAM_BUF_ERR; - goto go_out; + /* exec the mkhomedir helper */ + args[0] = x_strdup(MKHOMEDIR_HELPER); + args[1] = pwd->pw_name; + args[2] = x_strdup(opt->umask); + args[3] = x_strdup(opt->skeldir); + + execve(MKHOMEDIR_HELPER, args, envp); + + /* should not get here: exit with error */ + D(("helper binary is not available")); + _exit(PAM_SYSTEM_ERR); + } else if (child > 0) { + int rc; + while ((rc=waitpid(child, &retval, 0)) < 0 && errno == EINTR); + if (rc < 0) { + pam_syslog(pamh, LOG_ERR, "waitpid failed: %m"); + retval = PAM_SYSTEM_ERR; + } else if (!WIFEXITED(retval)) { + pam_syslog(pamh, LOG_ERR, "mkhomedir_helper abnormal exit: %d", retval); + retval = PAM_SYSTEM_ERR; + } else { + retval = WEXITSTATUS(retval); } - - sprintf (newdest, "%s/%s", dest, Dir->d_name); -#else - snprintf (newdest,sizeof (newdest),"%s/%s",dest,Dir->d_name); -#endif - - /* If it's a directory, recurse. */ - if (S_ISDIR(St.st_mode)) - { - retval = create_homedir (pamh, ctrl, pwd, newsource, newdest); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - if (retval != PAM_SUCCESS) - { - closedir(D); - goto go_out; - } - continue; - } - - /* If it's a symlink, create a new link. */ - if (S_ISLNK(St.st_mode)) - { - int pointedlen = 0; -#ifndef PATH_MAX - char *pointed = NULL; - { - int size = 100; - - while (1) { - pointed = (char *) malloc(size); - if ( ! pointed ) { - free(newsource); - free(newdest); - return PAM_BUF_ERR; - } - pointedlen = readlink (newsource, pointed, size); - if ( pointedlen < 0 ) break; - if ( pointedlen < size ) break; - free (pointed); - size *= 2; - } - } - if ( pointedlen < 0 ) - free(pointed); - else - pointed[pointedlen] = 0; -#else - char pointed[PATH_MAX]; - memset(pointed, 0, sizeof(pointed)); - - pointedlen = readlink(newsource, pointed, sizeof(pointed) - 1); -#endif - - if ( pointedlen >= 0 ) { - if(symlink(pointed, newdest) == 0) - { - if (lchown(newdest,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on link %s: %m", newdest); - closedir(D); -#ifndef PATH_MAX - free(pointed); - free(newsource); - free(newdest); -#endif - return PAM_PERM_DENIED; - } - } -#ifndef PATH_MAX - free(pointed); -#endif - } -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* If it's not a regular file, it's probably not a good idea to create - * the new device node, FIFO, or whatever it is. */ - if (!S_ISREG(St.st_mode)) - { -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - continue; - } - - /* Open the source file */ - if ((SrcFd = open(newsource,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to open src file %s: %m", newsource); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - if (stat(newsource,&St) != 0) - { - pam_syslog(pamh, LOG_DEBUG, "unable to stat src file %s: %m", - newsource); - close(SrcFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - - /* Open the dest file */ - if ((DestFd = open(newdest,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to open dest file %s: %m", newdest); - close(SrcFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - return PAM_PERM_DENIED; - } - - /* Set the proper ownership and permissions for the module. We make - the file a+w and then mask it with the set mask. This preseves - execute bits */ - if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 || - fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on copy %s: %m", newdest); - close(SrcFd); - close(DestFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - - /* Copy the file */ - do - { - Res = pam_modutil_read(SrcFd,remark,sizeof(remark)); - - if (Res == 0) - continue; - - if (Res > 0) { - if (pam_modutil_write(DestFd,remark,Res) == Res) - continue; - } - - /* If we get here, pam_modutil_read returned a -1 or - pam_modutil_write returned something unexpected. */ - pam_syslog(pamh, LOG_DEBUG, "unable to perform IO: %m"); - close(SrcFd); - close(DestFd); - closedir(D); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - - return PAM_PERM_DENIED; - } - while (Res != 0); - close(SrcFd); - close(DestFd); - -#ifndef PATH_MAX - free(newsource); newsource = NULL; - free(newdest); newdest = NULL; -#endif - + } else { + D(("fork failed")); + pam_syslog(pamh, LOG_ERR, "fork failed: %m"); + retval = PAM_SYSTEM_ERR; } - closedir(D); - retval = PAM_SUCCESS; + sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ - go_out: + if (opt->ctrl & MKHOMEDIR_DEBUG) { + pam_syslog(pamh, LOG_DEBUG, "mkhomedir_helper returned %d", retval); + } - if (chmod(dest,0777 & (~UMask)) != 0 || - chown(dest,pwd->pw_uid,pwd->pw_gid) != 0) - { - pam_syslog(pamh, LOG_DEBUG, - "unable to change perms on directory %s: %m", dest); - return PAM_PERM_DENIED; + if (retval != PAM_SUCCESS && !(opt->ctrl & MKHOMEDIR_QUIET)) { + pam_error(pamh, _("Unable to create and initialize directory '%s'."), + pwd->pw_dir); } + D(("returning %d", retval)); return retval; } @@ -454,19 +194,20 @@ PAM_EXTERN int pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) { - int retval, ctrl; + int retval; + options_t opt; const void *user; const struct passwd *pwd; struct stat St; /* Parse the flag values */ - ctrl = _pam_parse(pamh, flags, argc, argv); + _pam_parse(pamh, flags, argc, argv, &opt); /* Determine the user name so we can get the home directory */ retval = pam_get_item(pamh, PAM_USER, &user); if (retval != PAM_SUCCESS || user == NULL || *(const char *)user == '\0') { - pam_syslog(pamh, LOG_NOTICE, "user unknown"); + pam_syslog(pamh, LOG_NOTICE, "Cannot obtain the user name."); return PAM_USER_UNKNOWN; } @@ -474,16 +215,22 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, pwd = pam_modutil_getpwnam (pamh, user); if (pwd == NULL) { + pam_syslog(pamh, LOG_NOTICE, "User unknown."); D(("couldn't identify user %s", user)); return PAM_CRED_INSUFFICIENT; } /* Stat the home directory, if something exists then we assume it is correct and return a success*/ - if (stat(pwd->pw_dir,&St) == 0) + if (stat(pwd->pw_dir, &St) == 0) { + if (opt.ctrl & MKHOMEDIR_DEBUG) { + pam_syslog(pamh, LOG_DEBUG, "Home directory %s already exists.", + pwd->pw_dir); + } return PAM_SUCCESS; + } - return create_homedir(pamh,ctrl,pwd,SkelDir,pwd->pw_dir); + return create_homedir(pamh, &opt, pwd); } /* Ignore */ |