diff --git a/docbook5.patch b/docbook5.patch new file mode 100644 index 0000000..3e23423 --- /dev/null +++ b/docbook5.patch @@ -0,0 +1,20423 @@ +From 681e88a5428904b478a37e65154d7cf0ba1a9eb5 Mon Sep 17 00:00:00 2001 +From: Stefan Schubert +Date: Tue, 25 Oct 2022 16:29:41 +0200 +Subject: [PATCH] doc: Update PAM documentation from DockBook 4 to DocBook 5 + +Changed files +-------------- + +Make.xml.rules.in: +- Using RNG file instead of DTD file for checking XML files. +- Taking the correct stylesheet for README files. + +doc/sag/Makefile.am, doc/adg/Makefile.am, doc/mwg/Makefile.am: +- Using RNG file instead of DTD file for checking XML files. + +configure.ac: +- Added a new option for selecting RNG check file (-enable-docbook-rng) +- Switching stylesheets to docbook 5 +- Checking DocBook 5 environment instead of DocBook 4 environment + +*.xml: +Update from DockBook 4 to DocBook 5 +--- + Make.xml.rules.in | 10 +- + ci/install-dependencies.sh | 4 +- + configure.ac | 33 ++- + doc/adg/Linux-PAM_ADG.xml | 199 +++++++-------- + doc/adg/Makefile.am | 6 +- + doc/adg/pam_acct_mgmt.xml | 20 +- + doc/adg/pam_authenticate.xml | 20 +- + doc/adg/pam_chauthtok.xml | 20 +- + doc/adg/pam_close_session.xml | 20 +- + doc/adg/pam_conv.xml | 20 +- + doc/adg/pam_end.xml | 20 +- + doc/adg/pam_fail_delay.xml | 20 +- + doc/adg/pam_get_item.xml | 20 +- + doc/adg/pam_getenv.xml | 20 +- + doc/adg/pam_getenvlist.xml | 20 +- + doc/adg/pam_misc_conv.xml | 15 +- + doc/adg/pam_misc_drop_env.xml | 15 +- + doc/adg/pam_misc_paste_env.xml | 15 +- + doc/adg/pam_misc_setenv.xml | 15 +- + doc/adg/pam_open_session.xml | 20 +- + doc/adg/pam_putenv.xml | 20 +- + doc/adg/pam_set_item.xml | 20 +- + doc/adg/pam_setcred.xml | 20 +- + doc/adg/pam_start.xml | 20 +- + doc/adg/pam_strerror.xml | 20 +- + doc/man/misc_conv.3.xml | 35 ++- + doc/man/pam.3.xml | 40 ++- + doc/man/pam.8.xml | 85 ++++--- + doc/man/pam.conf-desc.xml | 7 +- + doc/man/pam.conf-dir.xml | 9 +- + doc/man/pam.conf-syntax.xml | 12 +- + doc/man/pam.conf.5.xml | 28 +-- + doc/man/pam_acct_mgmt.3.xml | 20 +- + doc/man/pam_authenticate.3.xml | 20 +- + doc/man/pam_chauthtok.3.xml | 20 +- + doc/man/pam_close_session.3.xml | 21 +- + doc/man/pam_conv.3.xml | 20 +- + doc/man/pam_end.3.xml | 21 +- + doc/man/pam_error.3.xml | 23 +- + doc/man/pam_fail_delay.3.xml | 27 +-- + doc/man/pam_get_authtok.3.xml | 33 ++- + doc/man/pam_get_data.3.xml | 21 +- + doc/man/pam_get_item.3.xml | 33 +-- + doc/man/pam_get_user.3.xml | 21 +- + doc/man/pam_getenv.3.xml | 20 +- + doc/man/pam_getenvlist.3.xml | 20 +- + doc/man/pam_info.3.xml | 23 +- + doc/man/pam_item_types_ext.inc.xml | 5 +- + doc/man/pam_item_types_std.inc.xml | 5 +- + doc/man/pam_misc_drop_env.3.xml | 21 +- + doc/man/pam_misc_paste_env.3.xml | 21 +- + doc/man/pam_misc_setenv.3.xml | 21 +- + doc/man/pam_open_session.3.xml | 21 +- + doc/man/pam_prompt.3.xml | 23 +- + doc/man/pam_putenv.3.xml | 20 +- + doc/man/pam_set_data.3.xml | 21 +- + doc/man/pam_set_item.3.xml | 33 +-- + doc/man/pam_setcred.3.xml | 21 +- + doc/man/pam_sm_acct_mgmt.3.xml | 22 +- + doc/man/pam_sm_authenticate.3.xml | 22 +- + doc/man/pam_sm_chauthtok.3.xml | 30 ++- + doc/man/pam_sm_close_session.3.xml | 22 +- + doc/man/pam_sm_open_session.3.xml | 22 +- + doc/man/pam_sm_setcred.3.xml | 24 +- + doc/man/pam_start.3.xml | 21 +- + doc/man/pam_strerror.3.xml | 21 +- + doc/man/pam_syslog.3.xml | 21 +- + doc/man/pam_xauth_data.3.xml | 21 +- + doc/mwg/Linux-PAM_MWG.xml | 178 ++++++-------- + doc/mwg/Makefile.am | 6 +- + doc/mwg/pam_conv.xml | 20 +- + doc/mwg/pam_fail_delay.xml | 20 +- + doc/mwg/pam_get_data.xml | 20 +- + doc/mwg/pam_get_item.xml | 20 +- + doc/mwg/pam_get_user.xml | 20 +- + doc/mwg/pam_getenv.xml | 20 +- + doc/mwg/pam_getenvlist.xml | 20 +- + doc/mwg/pam_putenv.xml | 20 +- + doc/mwg/pam_set_data.xml | 20 +- + doc/mwg/pam_set_item.xml | 20 +- + doc/mwg/pam_sm_acct_mgmt.xml | 20 +- + doc/mwg/pam_sm_authenticate.xml | 20 +- + doc/mwg/pam_sm_chauthtok.xml | 20 +- + doc/mwg/pam_sm_close_session.xml | 20 +- + doc/mwg/pam_sm_open_session.xml | 20 +- + doc/mwg/pam_sm_setcred.xml | 20 +- + doc/mwg/pam_strerror.xml | 20 +- + doc/sag/Linux-PAM_SAG.xml | 229 +++++++----------- + doc/sag/Makefile.am | 7 +- + doc/sag/pam_access.xml | 52 ++-- + doc/sag/pam_debug.xml | 42 ++-- + doc/sag/pam_deny.xml | 42 ++-- + doc/sag/pam_echo.xml | 42 ++-- + doc/sag/pam_env.xml | 52 ++-- + doc/sag/pam_exec.xml | 42 ++-- + doc/sag/pam_faildelay.xml | 42 ++-- + doc/sag/pam_faillock.xml | 47 ++-- + doc/sag/pam_filter.xml | 42 ++-- + doc/sag/pam_ftp.xml | 42 ++-- + doc/sag/pam_group.xml | 52 ++-- + doc/sag/pam_issue.xml | 42 ++-- + doc/sag/pam_keyinit.xml | 42 ++-- + doc/sag/pam_lastlog.xml | 42 ++-- + doc/sag/pam_limits.xml | 52 ++-- + doc/sag/pam_listfile.xml | 42 ++-- + doc/sag/pam_localuser.xml | 42 ++-- + doc/sag/pam_loginuid.xml | 42 ++-- + doc/sag/pam_mail.xml | 42 ++-- + doc/sag/pam_mkhomedir.xml | 42 ++-- + doc/sag/pam_motd.xml | 42 ++-- + doc/sag/pam_namespace.xml | 52 ++-- + doc/sag/pam_nologin.xml | 42 ++-- + doc/sag/pam_permit.xml | 42 ++-- + doc/sag/pam_pwhistory.xml | 47 ++-- + doc/sag/pam_rhosts.xml | 42 ++-- + doc/sag/pam_rootok.xml | 42 ++-- + doc/sag/pam_securetty.xml | 42 ++-- + doc/sag/pam_selinux.xml | 42 ++-- + doc/sag/pam_sepermit.xml | 47 ++-- + doc/sag/pam_setquota.xml | 42 ++-- + doc/sag/pam_shells.xml | 42 ++-- + doc/sag/pam_succeed_if.xml | 42 ++-- + doc/sag/pam_time.xml | 52 ++-- + doc/sag/pam_timestamp.xml | 52 ++-- + doc/sag/pam_tty_audit.xml | 47 ++-- + doc/sag/pam_umask.xml | 42 ++-- + doc/sag/pam_unix.xml | 42 ++-- + doc/sag/pam_userdb.xml | 42 ++-- + doc/sag/pam_warn.xml | 42 ++-- + doc/sag/pam_wheel.xml | 42 ++-- + doc/sag/pam_xauth.xml | 42 ++-- + examples/.gitignore | 2 +- + modules/pam_access/README.xml | 32 +-- + modules/pam_access/access.conf.5.xml | 20 +- + modules/pam_access/pam_access.8.xml | 63 +++-- + modules/pam_debug/README.xml | 32 +-- + modules/pam_debug/pam_debug.8.xml | 61 +++-- + modules/pam_deny/README.xml | 29 +-- + modules/pam_deny/pam_deny.8.xml | 29 +-- + modules/pam_echo/README.xml | 29 +-- + modules/pam_echo/pam_echo.8.xml | 45 ++-- + modules/pam_env/README.xml | 34 +-- + modules/pam_env/pam_env.8.xml | 59 +++-- + modules/pam_env/pam_env.conf.5.xml | 19 +- + modules/pam_exec/README.xml | 32 +-- + modules/pam_exec/pam_exec.8.xml | 65 +++-- + modules/pam_faildelay/README.xml | 32 +-- + modules/pam_faildelay/pam_faildelay.8.xml | 37 ++- + modules/pam_faillock/README.xml | 35 +-- + modules/pam_faillock/faillock.8.xml | 41 ++-- + modules/pam_faillock/faillock.conf.5.xml | 53 ++-- + modules/pam_faillock/pam_faillock.8.xml | 74 +++--- + modules/pam_filter/README.xml | 32 +-- + modules/pam_filter/pam_filter.8.xml | 51 ++-- + modules/pam_ftp/README.xml | 32 +-- + modules/pam_ftp/pam_ftp.8.xml | 41 ++-- + modules/pam_group/README.xml | 29 +-- + modules/pam_group/group.conf.5.xml | 19 +- + modules/pam_group/pam_group.8.xml | 31 ++- + modules/pam_issue/README.xml | 32 +-- + modules/pam_issue/pam_issue.8.xml | 63 +++-- + modules/pam_keyinit/README.xml | 32 +-- + modules/pam_keyinit/pam_keyinit.8.xml | 47 ++-- + modules/pam_lastlog/README.xml | 32 +-- + modules/pam_lastlog/pam_lastlog.8.xml | 77 +++--- + modules/pam_limits/README.xml | 32 +-- + modules/pam_limits/limits.conf.5.xml | 111 ++++----- + modules/pam_limits/pam_limits.8.xml | 55 ++--- + modules/pam_listfile/README.xml | 32 +-- + modules/pam_listfile/pam_listfile.8.xml | 53 ++-- + modules/pam_localuser/README.xml | 32 +-- + modules/pam_localuser/pam_localuser.8.xml | 41 ++-- + modules/pam_loginuid/README.xml | 29 +-- + modules/pam_loginuid/pam_loginuid.8.xml | 33 ++- + modules/pam_mail/README.xml | 32 +-- + modules/pam_mail/pam_mail.8.xml | 73 +++--- + modules/pam_mkhomedir/README.xml | 29 +-- + modules/pam_mkhomedir/mkhomedir_helper.8.xml | 29 +-- + modules/pam_mkhomedir/pam_mkhomedir.8.xml | 49 ++-- + modules/pam_motd/README.xml | 32 +-- + modules/pam_motd/pam_motd.8.xml | 41 ++-- + modules/pam_namespace/README.xml | 37 +-- + modules/pam_namespace/namespace.conf.5.xml | 19 +- + modules/pam_namespace/pam_namespace.8.xml | 87 ++++--- + .../pam_namespace/pam_namespace_helper.8.xml | 21 +- + modules/pam_nologin/README.xml | 35 +-- + modules/pam_nologin/pam_nologin.8.xml | 39 ++- + modules/pam_permit/README.xml | 32 +-- + modules/pam_permit/pam_permit.8.xml | 29 +-- + modules/pam_pwhistory/README.xml | 32 +-- + modules/pam_pwhistory/pam_pwhistory.8.xml | 65 +++-- + modules/pam_pwhistory/pwhistory.conf.5.xml | 39 ++- + modules/pam_pwhistory/pwhistory_helper.8.xml | 23 +- + modules/pam_rhosts/README.xml | 32 +-- + modules/pam_rhosts/pam_rhosts.8.xml | 35 ++- + modules/pam_rootok/README.xml | 32 +-- + modules/pam_rootok/pam_rootok.8.xml | 35 ++- + modules/pam_securetty/README.xml | 32 +-- + modules/pam_securetty/pam_securetty.8.xml | 41 ++-- + modules/pam_selinux/README.xml | 32 +-- + modules/pam_selinux/pam_selinux.8.xml | 65 +++-- + modules/pam_sepermit/README.xml | 32 +-- + modules/pam_sepermit/pam_sepermit.8.xml | 41 ++-- + modules/pam_sepermit/sepermit.conf.5.xml | 29 +-- + modules/pam_setquota/README.xml | 32 +-- + modules/pam_setquota/pam_setquota.8.xml | 64 +++-- + modules/pam_shells/README.xml | 32 +-- + modules/pam_shells/pam_shells.8.xml | 29 +-- + modules/pam_stress/README.xml | 26 +- + modules/pam_stress/pam_stress.8.xml | 71 +++--- + modules/pam_succeed_if/README.xml | 32 +-- + modules/pam_succeed_if/pam_succeed_if.8.xml | 78 +++--- + modules/pam_time/README.xml | 29 +-- + modules/pam_time/pam_time.8.xml | 45 ++-- + modules/pam_time/time.conf.5.xml | 23 +- + modules/pam_timestamp/README.xml | 35 +-- + modules/pam_timestamp/pam_timestamp.8.xml | 53 ++-- + .../pam_timestamp/pam_timestamp_check.8.xml | 45 ++-- + modules/pam_tty_audit/README.xml | 30 +-- + modules/pam_tty_audit/pam_tty_audit.8.xml | 47 ++-- + modules/pam_umask/README.xml | 32 +-- + modules/pam_umask/pam_umask.8.xml | 51 ++-- + modules/pam_unix/README.xml | 32 +-- + modules/pam_unix/pam_unix.8.xml | 89 ++++--- + modules/pam_unix/unix_chkpwd.8.xml | 23 +- + modules/pam_unix/unix_update.8.xml | 23 +- + modules/pam_userdb/README.xml | 32 +-- + modules/pam_userdb/pam_userdb.8.xml | 67 +++-- + modules/pam_usertype/README.xml | 32 +-- + modules/pam_usertype/pam_usertype.8.xml | 42 ++-- + modules/pam_warn/README.xml | 32 +-- + modules/pam_warn/pam_warn.8.xml | 31 ++- + modules/pam_wheel/README.xml | 32 +-- + modules/pam_wheel/pam_wheel.8.xml | 59 +++-- + modules/pam_xauth/README.xml | 35 +-- + modules/pam_xauth/pam_xauth.8.xml | 65 +++-- + 236 files changed, 3398 insertions(+), 5101 deletions(-) + +diff --git a/Make.xml.rules.in b/Make.xml.rules.in +index 27bb510ec..98beb9ed7 100644 +--- a/Make.xml.rules.in ++++ b/Make.xml.rules.in +@@ -5,22 +5,22 @@ + README: $(XMLS) + + README: README.xml +- $(XSLTPROC) --path $(srcdir) --xinclude --stringparam generate.toc "none" @STRINGPARAM_VENDORDIR@ --nonet $(top_srcdir)/doc/custom-html.xsl $< | $(BROWSER) > $(srcdir)/$@ ++ $(XSLTPROC) --path $(srcdir) --xinclude --stringparam generate.toc "none" @STRINGPARAM_VENDORDIR@ --nonet $(TXT_STYLESHEET) $< | $(BROWSER) > $(srcdir)/$@ + + %.1: %.1.xml +- $(XMLLINT) --nonet --xinclude --postvalid --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noout $< + $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ --nonet $(top_srcdir)/doc/custom-man.xsl $< + + %.3: %.3.xml +- $(XMLLINT) --nonet --xinclude --postvalid --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noout $< + $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ --nonet $(top_srcdir)/doc/custom-man.xsl $< + + %.5: %.5.xml +- $(XMLLINT) --nonet --xinclude --postvalid --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noout $< + $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ --nonet $(top_srcdir)/doc/custom-man.xsl $< + + %.8: %.8.xml +- $(XMLLINT) --nonet --xinclude --postvalid --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noout $< + $(XSLTPROC) -o $(srcdir)/$@ --path $(srcdir) --xinclude @STRINGPARAM_VENDORDIR@ @STRINGPARAM_HMAC@ --nonet $(top_srcdir)/doc/custom-man.xsl $< + + #CLEANFILES += $(man_MANS) README +diff --git a/configure.ac b/configure.ac +index 2f74d1b49..84cda219d 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -243,26 +243,35 @@ if test x"$enable_debug" = x"yes" ; then + [lots of stuff gets written to /var/run/pam-debug.log]) + fi + ++AC_ARG_ENABLE(docbook_rng, ++ AS_HELP_STRING([--enable-docbook-rng=FILE],[RNG file for checking XML files @<:@default=http://docbook.org/xml/5.0/rng/docbookxi.rng@:>@]), ++ DOCBOOK_RNG=$enableval, DOCBOOK_RNG=http://docbook.org/xml/5.0/rng/docbookxi.rng) ++AC_SUBST(DOCBOOK_RNG) ++ + AC_ARG_ENABLE(html_stylesheet, +- AS_HELP_STRING([--enable-html-stylesheet=FILE],[html stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl@:>@]), +- HTML_STYLESHEET=$enableval, HTML_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl) ++ AS_HELP_STRING([--enable-html-stylesheet=FILE],[html stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl-ns/current/html/chunk.xsl@:>@]), ++ HTML_STYLESHEET=$enableval, HTML_STYLESHEET=http://docbook.sourceforge.net/release/xsl-ns/current/html/chunk.xsl) + AC_SUBST(HTML_STYLESHEET) + + AC_ARG_ENABLE(txt_stylesheet, +- AS_HELP_STRING([--enable-txt-stylesheet=FILE],[text stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl@:>@]), +- TXT_STYLESHEET=$enableval, TXT_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl) ++ AS_HELP_STRING([--enable-txt-stylesheet=FILE],[text stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl-ns/current/html/docbook.xsl@:>@]), ++ TXT_STYLESHEET=$enableval, TXT_STYLESHEET=http://docbook.sourceforge.net/release/xsl-ns/current/html/docbook.xsl) ++ ++ + AC_SUBST(TXT_STYLESHEET) + # It has to be TXT_STYLESHEET otherwise a html tree will be generated while generating all README files. + sed "s+HTML_STYLESHEET+$TXT_STYLESHEET+g" doc/custom-html.xsl + + AC_ARG_ENABLE(pdf_stylesheet, +- AS_HELP_STRING([--enable-pdf-stylesheet=FILE],[pdf stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl@:>@]), +- PDF_STYLESHEET=$enableval, PDF_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl) ++ AS_HELP_STRING([--enable-pdf-stylesheet=FILE],[pdf stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl-ns/current/fo/docbook.xsl@:>@]), ++ PDF_STYLESHEET=$enableval, PDF_STYLESHEET=http://docbook.sourceforge.net/release/xsl-ns/current/fo/docbook.xsl) + AC_SUBST(PDF_STYLESHEET) + + AC_ARG_ENABLE(man_stylesheet, +- AS_HELP_STRING([--enable-man-stylesheet=FILE],[man stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl@:>@]), +- MAN_STYLESHEET=$enableval, MAN_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl) ++ AS_HELP_STRING([--enable-man-stylesheet=FILE],[man stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl-ns/current/manpages/profile-docbook.xsl@:>@]), ++ MAN_STYLESHEET=$enableval, MAN_STYLESHEET=http://docbook.sourceforge.net/release/xsl-ns/current/manpages/profile-docbook.xsl) ++ ++ + AC_SUBST(MAN_STYLESHEET) + sed "s+MAN_STYLESHEET+$MAN_STYLESHEET+g" doc/custom-man.xsl + +@@ -605,10 +614,10 @@ if test -z "$XSLTPROC"; then + enable_docu=no + fi + AC_PATH_PROG([XMLLINT], [xmllint],[/bin/true]) +-dnl check for DocBook DTD and stylesheets in the local catalog. +-JH_CHECK_XML_CATALOG([-//OASIS//DTD DocBook XML V4.4//EN], +- [DocBook XML DTD V4.4], [], enable_docu=no) +-JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl], ++dnl check for DocBook RNG and stylesheets in the local catalog. ++JH_CHECK_XML_CATALOG([http://docbook.org/xml/5.0/rng/docbookxi.rng], ++ [DocBook XML RNG V5.0], [], enable_docu=no) ++JH_CHECK_XML_CATALOG([http://docbook.sourceforge.net/release/xsl-ns/current/manpages/docbook.xsl], + [DocBook XSL Stylesheets], [], enable_docu=no) + + AC_PATH_PROG([BROWSER], [w3m]) +diff --git a/doc/adg/Linux-PAM_ADG.xml b/doc/adg/Linux-PAM_ADG.xml +index 79452e17d..169e15cf1 100644 +--- a/doc/adg/Linux-PAM_ADG.xml ++++ b/doc/adg/Linux-PAM_ADG.xml +@@ -1,50 +1,39 @@ +- +- +- +- ++ ++ + The Linux-PAM Application Developers' Guide + +- +- Andrew G. +- Morgan +- morgan@kernel.org +- +- +- Thorsten +- Kukuk +- kukuk@thkukuk.de +- ++ Andrew G.Morganmorgan@kernel.org ++ ThorstenKukukkukuk@thkukuk.de + + Version 1.1.2, 31. August 2010 + + + This manual documents what an application developer needs to know +- about the Linux-PAM library. It ++ about the Linux-PAM library. It + describes how an application might use the +- Linux-PAM library to authenticate ++ Linux-PAM library to authenticate + users. In addition it contains a description of the functions + to be found in libpam_misc library, that can + be used in general applications. Finally, it contains some comments + on PAM related security issues for the application developer. + + +- ++ + +- ++ + Introduction +-
++
+ Description + +- Linux-PAM ++ Linux-PAM + (Pluggable Authentication Modules for Linux) is a library that enables + the local system administrator to choose how individual applications + authenticate users. For an overview of the +- Linux-PAM library see the ++ Linux-PAM library see the + Linux-PAM System Administrators' Guide. + + +- It is the purpose of the Linux-PAM ++ It is the purpose of the Linux-PAM + project to liberate the development of privilege granting software + from the development of secure and appropriate authentication schemes. + This is accomplished by providing a documented library of functions +@@ -64,11 +53,11 @@ + +
+ +-
++
+ Synopsis + + For general applications that wish to use the services provided by +- Linux-PAM the following is a summary ++ Linux-PAM the following is a summary + of the relevant linking information: + + #include <security/pam_appl.h> +@@ -92,7 +81,7 @@ cc -o application .... -lpam -lpam_misc +
+ + +- ++ + Overview + + Most service-giving applications are restricted. In other words, +@@ -108,7 +97,7 @@ cc -o application .... -lpam -lpam_misc + authentication-token (password changing) management services. It is + important to realize when writing a PAM based application that these + services are provided in a manner that is +- transparent to the application. That is ++ transparent to the application. That is + to say, when the application is written, no assumptions can be made + about how the client will be authenticated. + +@@ -206,74 +195,58 @@ cc -o application .... -lpam -lpam_misc + + + +- ++ + +- The public interface to <emphasis remap='B'>Linux-PAM</emphasis> ++ The public interface to <emphasis remap="B">Linux-PAM</emphasis> + + + Firstly, the relevant include file for the +- Linux-PAM library is ++ Linux-PAM library is + <security/pam_appl.h>. + It contains the definitions for a number of functions. After + listing these functions, we collect some guiding remarks for + programmers. + +-
++
+ What can be expected by the application +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ +
+-
++
+ What is expected of an application +- ++ +
+-
++
+ Programming notes + + Note, all of the authentication service function calls accept the +- token PAM_SILENT, which instructs ++ token PAM_SILENT, which instructs + the modules to not send messages to the application. This token + can be logically OR'd with any one of the permitted tokens specific + to the individual function calls. +- PAM_SILENT does not override the ++ PAM_SILENT does not override the + prompting of the user for passwords etc., it only stops informative + messages from being generated. + +
+ + +- ++ + +- Security issues of <emphasis remap='B'>Linux-PAM</emphasis> ++ Security issues of <emphasis remap="B">Linux-PAM</emphasis> + + + PAM, from the perspective of an application, is a convenient API for +@@ -284,19 +257,19 @@ cc -o application .... -lpam -lpam_misc + + + A poorly (or maliciously) written application can defeat any +- Linux-PAM module's authentication ++ Linux-PAM module's authentication + mechanisms by simply ignoring it's return values. It is the + applications task and responsibility to grant privileges and access +- to services. The Linux-PAM library ++ to services. The Linux-PAM library + simply assumes the responsibility of authenticating + the user; ascertaining that the user is who they + say they are. Care should be taken to anticipate all of the documented +- behavior of the Linux-PAM library ++ behavior of the Linux-PAM library + functions. A failure to do this will most certainly lead to a future + security breach. + + +-
++
+ Care about standard library calls + + In general, writers of authorization-granting applications should +@@ -308,9 +281,9 @@ cc -o application .... -lpam -lpam_misc + function is likely to corrupt a pointer previously + obtained by the application. The application programmer should + either re-call such a 'libc' function after a call to the +- Linux-PAM library, or copy the ++ Linux-PAM library, or copy the + structure contents to some safe area of memory before passing +- control to the Linux-PAM library. ++ control to the Linux-PAM library. + + + Two important function classes that fall into this category are +@@ -322,12 +295,12 @@ cc -o application .... -lpam -lpam_misc + +
+ +-
++
+ Choice of a service name + + When picking the service-name that + corresponds to the first entry in the +- Linux-PAM configuration file, ++ Linux-PAM configuration file, + the application programmer should avoid + the temptation of choosing something related to + argv[0]. It is a trivial matter for any user +@@ -352,11 +325,11 @@ cc -o application .... -lpam -lpam_misc + and then run ./preferred_name. + + +- By studying the Linux-PAM ++ By studying the Linux-PAM + configuration file(s), an attacker can choose the + preferred_name to be that of a service enjoying + minimal protection; for example a game which uses +- Linux-PAM to restrict access to ++ Linux-PAM to restrict access to + certain hours of the day. If the service-name were to be linked + to the filename under which the service was invoked, it + is clear that the user is effectively in the position of +@@ -370,7 +343,7 @@ cc -o application .... -lpam -lpam_misc + +
+ +-
++
+ The conversation function + + Care should be taken to ensure that the conv() +@@ -380,10 +353,10 @@ cc -o application .... -lpam -lpam_misc + +
+ +-
++
+ The identity of the user + +- The Linux-PAM modules will need ++ The Linux-PAM modules will need + to determine the identity of the user who requests a service, + and the identity of the user who grants the service. These two + users will seldom be the same. Indeed there is generally a third +@@ -444,7 +417,7 @@ cc -o application .... -lpam -lpam_misc + +
+ +-
++
+ Sufficient resources + + Care should be taken to ensure that the proper execution of an +@@ -465,7 +438,7 @@ cc -o application .... -lpam -lpam_misc +
+ + +- ++ + A library of miscellaneous helper functions + + To aid the work of the application developer a library of +@@ -479,24 +452,20 @@ cc -o application .... -lpam -lpam_misc + library can be defined by including + <security/pam_misc.h>. It should be + noted that this library is specific to +- Linux-PAM and is not referred to in ++ Linux-PAM and is not referred to in + the defining DCE-RFC (see See also) + below. + +-
++
+ Functions supplied +- +- +- +- ++ ++ ++ ++ +
+ + +- ++ + Porting legacy applications + + The point of PAM is that the application is not supposed to +@@ -545,7 +514,7 @@ cc -o application .... -lpam -lpam_misc + + + +- ++ + Glossary of PAM related terms + + The following are a list of terms used within this document. +@@ -585,17 +554,17 @@ cc -o application .... -lpam -lpam_misc + + + +- ++ + An example application + +- To get a flavor of the way a Linux-PAM ++ To get a flavor of the way a Linux-PAM + application is written we include the following example. It prompts + the user for their password and indicates whether their account + is valid on the standard output, its return code also indicates + the success (0 for success; + 1 for failure). + +- + /* + This program was contributed by Shane Watts + [modifications by AGM and kukuk] +@@ -607,9 +576,9 @@ cc -o application .... -lpam -lpam_misc + account required pam_unix.so + */ + +-#include +-#include +-#include ++#include <security/pam_appl.h> ++#include <security/pam_misc.h> ++#include <stdio.h> + + static struct pam_conv conv = { + misc_conv, +@@ -626,12 +595,12 @@ int main(int argc, char *argv[]) + user = argv[1]; + } + +- if(argc > 2) { ++ if(argc > 2) { + fprintf(stderr, "Usage: check_user [username]\n"); + exit(1); + } + +- retval = pam_start("check_user", user, &conv, &pamh); ++ retval = pam_start("check_user", user, &conv, &pamh); + + if (retval == PAM_SUCCESS) + retval = pam_authenticate(pamh, 0); /* is user really user? */ +@@ -655,24 +624,24 @@ int main(int argc, char *argv[]) + + return ( retval == PAM_SUCCESS ? 0:1 ); /* indicate success */ + } +-]]> ++ + + + +- ++ + Files + + +- /usr/include/security/pam_appl.h ++ /usr/include/security/pam_appl.h + + + Header file with interfaces for +- Linux-PAM applications. ++ Linux-PAM applications. + + + + +- /usr/include/security/pam_misc.h ++ /usr/include/security/pam_misc.h + + + Header file for useful library functions for making +@@ -683,7 +652,7 @@ int main(int argc, char *argv[]) + + + +- ++ + See also + + +@@ -706,7 +675,7 @@ int main(int argc, char *argv[]) + + + +- ++ + Author/acknowledgments + + This document was written by Andrew G. Morgan (morgan@kernel.org) +@@ -726,14 +695,14 @@ int main(int argc, char *argv[]) + + Thanks are also due to Sun Microsystems, especially to Vipin Samar and + Charlie Lai for their advice. At an early stage in the development of +- Linux-PAM, Sun graciously made the ++ Linux-PAM, Sun graciously made the + documentation for their implementation of PAM available. This act + greatly accelerated the development of +- Linux-PAM. ++ Linux-PAM. + + + +- ++ + Copyright information for this document + + Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> +@@ -777,4 +746,4 @@ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + + +- ++ +\ No newline at end of file +diff --git a/doc/adg/Makefile.am b/doc/adg/Makefile.am +index b795b1a46..77abdb717 100644 +--- a/doc/adg/Makefile.am ++++ b/doc/adg/Makefile.am +@@ -16,7 +16,7 @@ all: Linux-PAM_ADG.txt html/Linux-PAM_ADG.html Linux-PAM_ADG.pdf + + Linux-PAM_ADG.pdf: $(XMLS) $(DEP_XMLS) + if ENABLE_GENERATE_PDF +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -28,7 +28,7 @@ else + endif + + Linux-PAM_ADG.txt: $(XMLS) $(DEP_XMLS) +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -37,7 +37,7 @@ Linux-PAM_ADG.txt: $(XMLS) $(DEP_XMLS) + + html/Linux-PAM_ADG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam base.dir html/ \ + --stringparam root.filename Linux-PAM_ADG \ + --stringparam use.id.as.filename 1 \ +diff --git a/doc/adg/pam_acct_mgmt.xml b/doc/adg/pam_acct_mgmt.xml +index 6a3a37d2c..afcf2f2f1 100644 +--- a/doc/adg/pam_acct_mgmt.xml ++++ b/doc/adg/pam_acct_mgmt.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Account validation management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_authenticate.xml b/doc/adg/pam_authenticate.xml +index 2ca9b540b..aa36c6870 100644 +--- a/doc/adg/pam_authenticate.xml ++++ b/doc/adg/pam_authenticate.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Authenticating the user + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_chauthtok.xml b/doc/adg/pam_chauthtok.xml +index 1c613da7a..e6815dde6 100644 +--- a/doc/adg/pam_chauthtok.xml ++++ b/doc/adg/pam_chauthtok.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Updating authentication tokens + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_close_session.xml b/doc/adg/pam_close_session.xml +index 4b93fc3a5..ed83d7a1c 100644 +--- a/doc/adg/pam_close_session.xml ++++ b/doc/adg/pam_close_session.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ terminating PAM session management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_conv.xml b/doc/adg/pam_conv.xml +index 01b751277..b2ba876e8 100644 +--- a/doc/adg/pam_conv.xml ++++ b/doc/adg/pam_conv.xml +@@ -1,11 +1,7 @@ +- +- +-
++
+ The conversation function + +- ++ + + + struct pam_message { +@@ -24,12 +20,10 @@ struct pam_conv { + void *appdata_ptr; + }; + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_end.xml b/doc/adg/pam_end.xml +index efa328bec..5e7192550 100644 +--- a/doc/adg/pam_end.xml ++++ b/doc/adg/pam_end.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Termination of PAM transaction + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_fail_delay.xml b/doc/adg/pam_fail_delay.xml +index 589e1148b..d602a1f79 100644 +--- a/doc/adg/pam_fail_delay.xml ++++ b/doc/adg/pam_fail_delay.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Request a delay on failure + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_get_item.xml b/doc/adg/pam_get_item.xml +index f23c734b8..d12cb17d7 100644 +--- a/doc/adg/pam_get_item.xml ++++ b/doc/adg/pam_get_item.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Getting PAM items + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_getenv.xml b/doc/adg/pam_getenv.xml +index 61d69c33c..f7b483ed9 100644 +--- a/doc/adg/pam_getenv.xml ++++ b/doc/adg/pam_getenv.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Get a PAM environment variable + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_getenvlist.xml b/doc/adg/pam_getenvlist.xml +index d3c2fcd35..4433c04d6 100644 +--- a/doc/adg/pam_getenvlist.xml ++++ b/doc/adg/pam_getenvlist.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Getting the PAM environment + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_misc_conv.xml b/doc/adg/pam_misc_conv.xml +index 2dc760cc3..4f54e11a4 100644 +--- a/doc/adg/pam_misc_conv.xml ++++ b/doc/adg/pam_misc_conv.xml +@@ -1,14 +1,9 @@ +- +- +-
++
+ Text based conversation function + +- ++ + +-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_misc_drop_env.xml b/doc/adg/pam_misc_drop_env.xml +index 956d48156..cacb770e0 100644 +--- a/doc/adg/pam_misc_drop_env.xml ++++ b/doc/adg/pam_misc_drop_env.xml +@@ -1,14 +1,9 @@ +- +- +-
++
+ Liberating a locally saved environment + +- ++ + +-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_misc_paste_env.xml b/doc/adg/pam_misc_paste_env.xml +index c6d3856bc..8ab2440ab 100644 +--- a/doc/adg/pam_misc_paste_env.xml ++++ b/doc/adg/pam_misc_paste_env.xml +@@ -1,14 +1,9 @@ +- +- +-
++
+ Transcribing an environment to that of PAM + +- ++ + +-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_misc_setenv.xml b/doc/adg/pam_misc_setenv.xml +index 3b1a32e44..7e8c489b6 100644 +--- a/doc/adg/pam_misc_setenv.xml ++++ b/doc/adg/pam_misc_setenv.xml +@@ -1,14 +1,9 @@ +- +- +-
++
+ BSD like PAM environment variable setting + +- ++ + +-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_open_session.xml b/doc/adg/pam_open_session.xml +index ba738a552..10afa755f 100644 +--- a/doc/adg/pam_open_session.xml ++++ b/doc/adg/pam_open_session.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Start PAM session management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_putenv.xml b/doc/adg/pam_putenv.xml +index e55f1a42f..6378a15b2 100644 +--- a/doc/adg/pam_putenv.xml ++++ b/doc/adg/pam_putenv.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Set or change PAM environment variable + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_set_item.xml b/doc/adg/pam_set_item.xml +index 411693874..efc4292b1 100644 +--- a/doc/adg/pam_set_item.xml ++++ b/doc/adg/pam_set_item.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Setting PAM items + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_setcred.xml b/doc/adg/pam_setcred.xml +index 1d3d23cdd..488028cd9 100644 +--- a/doc/adg/pam_setcred.xml ++++ b/doc/adg/pam_setcred.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Setting user credentials + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_start.xml b/doc/adg/pam_start.xml +index e5ec84818..c7ee4494a 100644 +--- a/doc/adg/pam_start.xml ++++ b/doc/adg/pam_start.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Initialization of PAM transaction + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/adg/pam_strerror.xml b/doc/adg/pam_strerror.xml +index 35b08a274..e4e1c56af 100644 +--- a/doc/adg/pam_strerror.xml ++++ b/doc/adg/pam_strerror.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Strings describing PAM error codes + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/man/misc_conv.3.xml b/doc/man/misc_conv.3.xml +index d902ba838..92d4acd19 100644 +--- a/doc/man/misc_conv.3.xml ++++ b/doc/man/misc_conv.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + misc_conv + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + misc_conv + text based conversation function + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_misc.h> + + int misc_conv +@@ -30,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The misc_conv function is part of +@@ -50,7 +47,7 @@ + + + +- time_t pam_misc_conv_warn_time; ++ time_t pam_misc_conv_warn_time; + + + This variable contains the time (as +@@ -67,7 +64,7 @@ + + + +- const char *pam_misc_conv_warn_line; ++ const char *pam_misc_conv_warn_line; + + + Used in conjunction with +@@ -83,7 +80,7 @@ + + + +- time_t pam_misc_conv_die_time; ++ time_t pam_misc_conv_die_time; + + + This variable contains the time (as +@@ -100,7 +97,7 @@ + + + +- const char *pam_misc_conv_die_line; ++ const char *pam_misc_conv_die_line; + + + Used in conjunction with +@@ -116,7 +113,7 @@ + + + +- int pam_misc_conv_died; ++ int pam_misc_conv_died; + + + Following a return from the Linux-PAM +@@ -136,7 +133,7 @@ + + + +- int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t *prompt_p); ++ int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t *prompt_p); + + + +@@ -151,7 +148,7 @@ + + + +- int (*pam_binary_handler_free)(void *appdata, pamc_bp_t *delete_me); ++ int (*pam_binary_handler_free)(void *appdata, pamc_bp_t *delete_me); + + + +@@ -164,7 +161,7 @@ + + + +- ++ + SEE ALSO + + +@@ -176,7 +173,7 @@ + + + +- ++ + STANDARDS + + The misc_conv function is part of the +@@ -185,4 +182,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam.3.xml b/doc/man/pam.3.xml +index 0b1efccf4..4b8280160 100644 +--- a/doc/man/pam.3.xml ++++ b/doc/man/pam.3.xml +@@ -1,20 +1,18 @@ +- +- +- ++ + + + pam + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam + Pluggable Authentication Modules Library + + +- ++ + + #include <security/pam_appl.h> + #include <security/pam_modules.h> +@@ -22,10 +20,10 @@ + + + +- ++ + DESCRIPTION + +- PAM is a system of libraries ++ PAM is a system of libraries + that handle the authentication tasks of applications (services) + on the system. The library provides a stable general interface + (Application Programming Interface - API) that privilege granting +@@ -38,7 +36,7 @@ + defer to to perform standard authentication tasks. + + +- ++ + Initialization and Cleanup + + The +@@ -64,7 +62,7 @@ + + + +- ++ + Authentication + + The +@@ -85,7 +83,7 @@ + + + +- ++ + Account Management + + The +@@ -98,7 +96,7 @@ + + + +- ++ + Password Management + + The +@@ -109,7 +107,7 @@ + + + +- ++ + Session Management + + The +@@ -124,7 +122,7 @@ + + + +- ++ + Conversation + + The PAM library uses an application-defined callback to allow +@@ -141,7 +139,7 @@ + + + +- ++ + Data Objects + + The +@@ -176,7 +174,7 @@ + + + +- ++ + Environment and Error Management + + The +@@ -202,7 +200,7 @@ + + + +- ++ + RETURN VALUES + + The following return codes are known by PAM: +@@ -389,7 +387,7 @@ + + + +- SEE ALSO ++ SEE ALSO + + + pam_acct_mgmt3 +@@ -430,10 +428,10 @@ + + + +- NOTES ++ NOTES + + The libpam interfaces are only thread-safe if each + thread within the multithreaded application uses its own PAM handle. + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam.8.xml b/doc/man/pam.8.xml +index 8eef665a0..20cd19d9c 100644 +--- a/doc/man/pam.8.xml ++++ b/doc/man/pam.8.xml +@@ -1,32 +1,29 @@ +- +- +- +- ++ + + + pam + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + PAM + pam + Pluggable Authentication Modules for Linux + + +- ++ + DESCRIPTION + + This manual is intended to offer a quick introduction to +- Linux-PAM. For more information ++ Linux-PAM. For more information + the reader is directed to the +- Linux-PAM system administrators' guide. ++ Linux-PAM system administrators' guide. + + + +- Linux-PAM is a system of libraries ++ Linux-PAM is a system of libraries + that handle the authentication tasks of applications (services) on + the system. The library provides a stable general interface + (Application Programming Interface - API) that privilege granting +@@ -43,12 +40,12 @@ + system administrator is free to choose how individual + service-providing applications will authenticate users. This dynamic + configuration is set by the contents of the single +- Linux-PAM configuration file ++ Linux-PAM configuration file + /etc/pam.conf. Alternatively, the configuration + can be set by individual configuration files located in the + /etc/pam.d/ directory. The presence of this +- directory will cause Linux-PAM to +- ignore /etc/pam.conf. ++ directory will cause Linux-PAM to ++ ignore /etc/pam.conf. + + + +@@ -64,26 +61,26 @@ + From the point of view of the system administrator, for whom this + manual is provided, it is not of primary importance to understand the + internal behavior of the +-Linux-PAM ++Linux-PAM + library. The important point to recognize is that the configuration + file(s) +-define ++define + the connection between applications +-(services) ++(services) + and the pluggable authentication modules +-(PAMs) ++(PAMs) + that perform the actual authentication tasks. + + +-Linux-PAM ++Linux-PAM + separates the tasks of +-authentication ++authentication + into four independent management groups: +-account management; +-authentication management; +-password management; ++account management; ++authentication management; ++password management; + and +-session management. ++session management. + (We highlight the abbreviations used for these groups in the + configuration file.) + +@@ -92,12 +89,12 @@ configuration file.) + user's request for a restricted service: + + +-account - ++account - + provide account verification types of service: has the user's password + expired?; is this user permitted access to the requested service? + + +-authentication - ++authentication - + authenticate a user and set up user credentials. Typically this is via + some challenge-response request that the user must satisfy: if you are + who you claim to be please enter your password. Not all authentications +@@ -105,64 +102,64 @@ are of this type, there exist hardware based authentication schemes + (such as the use of smart-cards and biometric devices), with suitable + modules, these may be substituted seamlessly for more standard + approaches to authentication - such is the flexibility of +-Linux-PAM. ++Linux-PAM. + + +-password - ++password - + this group's responsibility is the task of updating authentication + mechanisms. Typically, such services are strongly coupled to those of + the +-auth ++auth + group. Some authentication mechanisms lend themselves well to being + updated with such a function. Standard UN*X password-based access is + the obvious example: please enter a replacement password. + + +-session - ++session - + this group of tasks cover things that should be done prior to a + service being given and after it is withdrawn. Such tasks include the + maintenance of audit trails and the mounting of the user's home + directory. The +-session ++session + management group is important as it provides both an opening and + closing hook for modules to affect the services available to a user. + + + +- ++ + FILES + + +- /etc/pam.conf ++ /etc/pam.conf + + the configuration file + + + +- /etc/pam.d ++ /etc/pam.d + + +- the Linux-PAM configuration ++ the Linux-PAM configuration + directory. Generally, if this directory is present, the + /etc/pam.conf file is ignored. + + + + +- /usr/lib/pam.d ++ /usr/lib/pam.d + + +- the Linux-PAM vendor configuration ++ the Linux-PAM vendor configuration + directory. Files in /etc/pam.d override + files with the same name in this directory. + + + + +- %vendordir%/pam.d ++ %vendordir%/pam.d + + +- the Linux-PAM vendor configuration ++ the Linux-PAM vendor configuration + directory. Files in /etc/pam.d and + /usr/lib/pam.d override files with the same + name in this directory. +@@ -172,18 +169,18 @@ closing hook for modules to affect the services available to a user. + + + +- ++ + ERRORS + + Typically errors generated by the +- Linux-PAM system of libraries, will ++ Linux-PAM system of libraries, will + be written to + syslog3 + . + + + +- ++ + CONFORMING TO + + DCE-RFC 86.0, October 1995. +@@ -192,7 +189,7 @@ closing hook for modules to affect the services available to a user. + + + +- ++ + SEE ALSO + + +@@ -212,4 +209,4 @@ closing hook for modules to affect the services available to a user. + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam.conf-desc.xml b/doc/man/pam.conf-desc.xml +index 909dcdbef..5dca89fe2 100644 +--- a/doc/man/pam.conf-desc.xml ++++ b/doc/man/pam.conf-desc.xml +@@ -1,7 +1,4 @@ +- +- +-
++
+ + When a PAM aware privilege granting application + is started, it activates its attachment to the PAM-API. This +@@ -18,4 +15,4 @@ + behavior of the PAM-API in the event that individual + PAMs fail. + +-
++
+\ No newline at end of file +diff --git a/doc/man/pam.conf-dir.xml b/doc/man/pam.conf-dir.xml +index 8446cf353..8272337b5 100644 +--- a/doc/man/pam.conf-dir.xml ++++ b/doc/man/pam.conf-dir.xml +@@ -1,7 +1,4 @@ +- +- +-
++
+ + More flexible than the single configuration file is it to + configure libpam via the contents of the +@@ -25,6 +22,6 @@ type control module-path module-arguments + The only difference being that the service-name is not present. The + service-name is of course the name of the given configuration file. + For example, /etc/pam.d/login contains the +- configuration for the login service. ++ configuration for the login service. + +-
++
+\ No newline at end of file +diff --git a/doc/man/pam.conf-syntax.xml b/doc/man/pam.conf-syntax.xml +index 5112f9301..c7d900811 100644 +--- a/doc/man/pam.conf-syntax.xml ++++ b/doc/man/pam.conf-syntax.xml +@@ -1,8 +1,4 @@ +- +- +- +-
++
+ + The syntax of the /etc/pam.conf + configuration file is as follows. The file is made up of a list +@@ -18,7 +14,7 @@ + + + +- service type control module-path module-arguments ++ service type control module-path module-arguments + + + +@@ -411,7 +407,7 @@ + should use `\]'. In other words: + + +- [..[..\]..] --> ..[..].. ++ [..[..\]..] --> ..[..].. + + + +@@ -424,4 +420,4 @@ + . + + +-
++
+\ No newline at end of file +diff --git a/doc/man/pam.conf.5.xml b/doc/man/pam.conf.5.xml +index 68f576afc..62a2b4108 100644 +--- a/doc/man/pam.conf.5.xml ++++ b/doc/man/pam.conf.5.xml +@@ -1,15 +1,13 @@ +- +- +- ++ + + + pam.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam.conf + pam.d + PAM configuration files +@@ -17,22 +15,16 @@ + + + +- ++ + DESCRIPTION +- ++ + +- ++ + +- ++ + + +- ++ + SEE ALSO + + +@@ -47,4 +39,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_acct_mgmt.3.xml b/doc/man/pam_acct_mgmt.3.xml +index 59760d7fc..de6a94aba 100644 +--- a/doc/man/pam_acct_mgmt.3.xml ++++ b/doc/man/pam_acct_mgmt.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_acct_mgmt + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_acct_mgmt + PAM account validation management + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_acct_mgmt +@@ -27,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_acct_mgmt function is used to determine +@@ -62,7 +60,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -122,7 +120,7 @@ + + + +- ++ + SEE ALSO + + +@@ -142,4 +140,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_authenticate.3.xml b/doc/man/pam_authenticate.3.xml +index c2004eb4a..794a5c711 100644 +--- a/doc/man/pam_authenticate.3.xml ++++ b/doc/man/pam_authenticate.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_authenticate + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_authenticate + account authentication + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_authenticate +@@ -27,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_authenticate function is used to +@@ -77,7 +75,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -146,7 +144,7 @@ + + + +- ++ + SEE ALSO + + +@@ -166,4 +164,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_chauthtok.3.xml b/doc/man/pam_chauthtok.3.xml +index f42bc68fb..e184f45fc 100644 +--- a/doc/man/pam_chauthtok.3.xml ++++ b/doc/man/pam_chauthtok.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_chauthtok + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_chauthtok + updating authentication tokens + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_chauthtok +@@ -27,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_chauthtok function is used to change the +@@ -64,7 +62,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -138,7 +136,7 @@ + + + +- ++ + SEE ALSO + + +@@ -161,4 +159,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_close_session.3.xml b/doc/man/pam_close_session.3.xml +index db549bdae..e1c74ebd4 100644 +--- a/doc/man/pam_close_session.3.xml ++++ b/doc/man/pam_close_session.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_close_session + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_close_session + terminate PAM session management + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_close_session +@@ -29,7 +26,7 @@ + + + +- ++ + DESCRIPTION + + The pam_close_session function is used +@@ -63,7 +60,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -101,7 +98,7 @@ + + + +- ++ + SEE ALSO + + +@@ -112,4 +109,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_conv.3.xml b/doc/man/pam_conv.3.xml +index 5106ddf7b..31834f3c9 100644 +--- a/doc/man/pam_conv.3.xml ++++ b/doc/man/pam_conv.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_conv + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_conv + PAM conversation function + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + +@@ -38,7 +36,7 @@ struct pam_conv { + + + +- ++ + DESCRIPTION + + The PAM library uses an application-defined callback to allow +@@ -174,7 +172,7 @@ struct pam_conv { + + + +- ++ + RETURN VALUES + + +@@ -205,7 +203,7 @@ struct pam_conv { + + + +- ++ + SEE ALSO + + +@@ -225,4 +223,4 @@ struct pam_conv { + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_end.3.xml b/doc/man/pam_end.3.xml +index 5febf85ad..b2584e732 100644 +--- a/doc/man/pam_end.3.xml ++++ b/doc/man/pam_end.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_end + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_end + termination of PAM transaction + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_end +@@ -29,7 +26,7 @@ + + + +- ++ + DESCRIPTION + + The pam_end function terminates the PAM +@@ -79,7 +76,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -102,7 +99,7 @@ + + + +- ++ + SEE ALSO + + +@@ -119,4 +116,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_error.3.xml b/doc/man/pam_error.3.xml +index de167f2c3..0f294c228 100644 +--- a/doc/man/pam_error.3.xml ++++ b/doc/man/pam_error.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_error + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_error + pam_verror + display error messages to the user +@@ -18,7 +15,7 @@ + + + +- ++ + + #include <security/pam_ext.h> + +@@ -36,7 +33,7 @@ + + + +- ++ + DESCRIPTION + + The pam_error function prints error messages +@@ -51,7 +48,7 @@ + variable argument list macros. + + +- ++ + RETURN VALUES + + +@@ -89,7 +86,7 @@ + + + +- ++ + SEE ALSO + + +@@ -110,7 +107,7 @@ + + + +- ++ + STANDARDS + + The pam_error and pam_verror +@@ -118,4 +115,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_fail_delay.3.xml b/doc/man/pam_fail_delay.3.xml +index 53c1f89e8..c400736a5 100644 +--- a/doc/man/pam_fail_delay.3.xml ++++ b/doc/man/pam_fail_delay.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_fail_delay + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_fail_delay + request a delay on failure + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_fail_delay +@@ -28,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_fail_delay function provides a +@@ -105,7 +102,7 @@ void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr); + + + +- ++ + RATIONALE + + It is often possible to attack an authentication scheme by exploiting +@@ -129,7 +126,7 @@ void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr); + + + +- ++ + EXAMPLE + + For example, a login application may require a failure delay of +@@ -161,7 +158,7 @@ module #2: pam_fail_delay (pamh, 4000000); + + + +- ++ + RETURN VALUES + + +@@ -183,7 +180,7 @@ module #2: pam_fail_delay (pamh, 4000000); + + + +- ++ + SEE ALSO + + +@@ -198,7 +195,7 @@ module #2: pam_fail_delay (pamh, 4000000); + + + +- ++ + STANDARDS + + The pam_fail_delay function is an +@@ -206,4 +203,4 @@ module #2: pam_fail_delay (pamh, 4000000); + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_get_authtok.3.xml b/doc/man/pam_get_authtok.3.xml +index 5d50b1684..ba6d955e9 100644 +--- a/doc/man/pam_get_authtok.3.xml ++++ b/doc/man/pam_get_authtok.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_get_authtok + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_get_authtok + pam_get_authtok_verify + pam_get_authtok_noverify +@@ -19,7 +16,7 @@ + + + +- ++ + + #include <security/pam_ext.h> + +@@ -44,7 +41,7 @@ + + + +- ++ + DESCRIPTION + + The pam_get_authtok function returns the +@@ -119,7 +116,7 @@ + + + +- ++ + OPTIONS + + pam_get_authtok honours the following module +@@ -128,7 +125,7 @@ + + + +- ++ try_first_pass + + + +@@ -140,7 +137,7 @@ + + + +- ++ use_first_pass + + + +@@ -153,7 +150,7 @@ + + + +- ++ use_authtok + + + +@@ -166,7 +163,7 @@ + + + +- ++ authtok_type=XXX + + + +@@ -182,7 +179,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -228,7 +225,7 @@ + + + +- ++ + SEE ALSO + + +@@ -237,7 +234,7 @@ + + + +- ++ + STANDARDS + + The pam_get_authtok function is a Linux-PAM +@@ -245,4 +242,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_get_data.3.xml b/doc/man/pam_get_data.3.xml +index e84e5a4c9..1e71cf3b1 100644 +--- a/doc/man/pam_get_data.3.xml ++++ b/doc/man/pam_get_data.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_get_data + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_get_data + + get module internal data +@@ -22,7 +19,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_get_data +@@ -35,7 +32,7 @@ + + + +- ++ + DESCRIPTION + + This function together with the +@@ -58,7 +55,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -90,7 +87,7 @@ + + + +- ++ + SEE ALSO + + +@@ -105,4 +102,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_get_item.3.xml b/doc/man/pam_get_item.3.xml +index 1145273c3..c30a279fa 100644 +--- a/doc/man/pam_get_item.3.xml ++++ b/doc/man/pam_get_item.3.xml +@@ -1,22 +1,13 @@ +- +- +- +---> +-]> +- +- ++ + + + pam_get_item + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_get_item + + getting PAM information +@@ -28,7 +19,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_get_item +@@ -41,7 +32,7 @@ + + + +- ++ + DESCRIPTION + + The pam_get_item function allows applications +@@ -55,16 +46,14 @@ + item_type: + + +- ++ + + + The following additional items are specific to Linux-PAM and should not be used in + portable applications: + + +- ++ + + + If a service module wishes to obtain the name of the user, +@@ -80,7 +69,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -128,7 +117,7 @@ + + + +- ++ + SEE ALSO + + +@@ -140,4 +129,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_get_user.3.xml b/doc/man/pam_get_user.3.xml +index 8bb176e49..121b3aa76 100644 +--- a/doc/man/pam_get_user.3.xml ++++ b/doc/man/pam_get_user.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_get_user + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_get_user + + get user name +@@ -22,7 +19,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_get_user +@@ -35,7 +32,7 @@ + + + +- ++ + DESCRIPTION + + The pam_get_user function returns the +@@ -87,7 +84,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -143,7 +140,7 @@ + + + +- ++ + SEE ALSO + + +@@ -161,4 +158,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_getenv.3.xml b/doc/man/pam_getenv.3.xml +index 7e8db015b..df25863b3 100644 +--- a/doc/man/pam_getenv.3.xml ++++ b/doc/man/pam_getenv.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_getenv + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_getenv + get a PAM environment variable + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + const char *pam_getenv +@@ -27,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_getenv function searches the +@@ -39,7 +37,7 @@ + + + +- ++ + RETURN VALUES + + The pam_getenv function returns NULL +@@ -47,7 +45,7 @@ + + + +- ++ + SEE ALSO + + +@@ -64,4 +62,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_getenvlist.3.xml b/doc/man/pam_getenvlist.3.xml +index 1c29b737d..54b1f411f 100644 +--- a/doc/man/pam_getenvlist.3.xml ++++ b/doc/man/pam_getenvlist.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_getenvlist + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_getenvlist + getting the PAM environment + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + char **pam_getenvlist +@@ -26,7 +24,7 @@ + + + +- ++ + DESCRIPTION + + The pam_getenvlist function returns a complete +@@ -57,7 +55,7 @@ + + + +- ++ + RETURN VALUES + + The pam_getenvlist function returns NULL +@@ -65,7 +63,7 @@ + + + +- ++ + SEE ALSO + + +@@ -82,4 +80,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_info.3.xml b/doc/man/pam_info.3.xml +index 88e671c7b..5155d4190 100644 +--- a/doc/man/pam_info.3.xml ++++ b/doc/man/pam_info.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_info + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_info + pam_vinfo + display messages to the user +@@ -18,7 +15,7 @@ + + + +- ++ + + #include <security/pam_ext.h> + +@@ -36,7 +33,7 @@ + + + +- ++ + DESCRIPTION + + The pam_info function prints messages +@@ -51,7 +48,7 @@ + variable argument list macros. + + +- ++ + RETURN VALUES + + +@@ -89,7 +86,7 @@ + + + +- ++ + SEE ALSO + + +@@ -98,7 +95,7 @@ + + + +- ++ + STANDARDS + + The pam_info and pam_vinfo +@@ -106,4 +103,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_item_types_ext.inc.xml b/doc/man/pam_item_types_ext.inc.xml +index d36a5bd1d..a5fee9c26 100644 +--- a/doc/man/pam_item_types_ext.inc.xml ++++ b/doc/man/pam_item_types_ext.inc.xml +@@ -1,6 +1,5 @@ + +- +- ++ + + PAM_FAIL_DELAY + +@@ -58,4 +57,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_item_types_std.inc.xml b/doc/man/pam_item_types_std.inc.xml +index 81f240b05..9b229486d 100644 +--- a/doc/man/pam_item_types_std.inc.xml ++++ b/doc/man/pam_item_types_std.inc.xml +@@ -1,6 +1,5 @@ + +- +- ++ + + PAM_SERVICE + +@@ -135,4 +134,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_misc_drop_env.3.xml b/doc/man/pam_misc_drop_env.3.xml +index 1941f5899..a7f6cc80e 100644 +--- a/doc/man/pam_misc_drop_env.3.xml ++++ b/doc/man/pam_misc_drop_env.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_misc_drop_env + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_misc_drop_env + liberating a locally saved environment + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_misc.h> + + int pam_misc_drop_env +@@ -27,7 +24,7 @@ + + + +- ++ + DESCRIPTION + + This function is defined to complement the +@@ -39,7 +36,7 @@ + + + +- ++ + SEE ALSO + + +@@ -51,7 +48,7 @@ + + + +- ++ + STANDARDS + + The pam_misc_drop_env function is part of the +@@ -60,4 +57,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_misc_paste_env.3.xml b/doc/man/pam_misc_paste_env.3.xml +index d9a282c0b..06194a9d9 100644 +--- a/doc/man/pam_misc_paste_env.3.xml ++++ b/doc/man/pam_misc_paste_env.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_misc_paste_env + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_misc_paste_env + transcribing an environment to that of PAM + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_misc.h> + + int pam_misc_paste_env +@@ -28,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + This function takes the supplied list of environment pointers and +@@ -37,7 +34,7 @@ + + + +- ++ + SEE ALSO + + +@@ -49,7 +46,7 @@ + + + +- ++ + STANDARDS + + The pam_misc_paste_env function is part of the +@@ -58,4 +55,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_misc_setenv.3.xml b/doc/man/pam_misc_setenv.3.xml +index 7e61a8dd5..4414d54db 100644 +--- a/doc/man/pam_misc_setenv.3.xml ++++ b/doc/man/pam_misc_setenv.3.xml +@@ -1,15 +1,12 @@ +- +- +- +- ++ + + + pam_misc_setenv + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + +- ++ + pam_misc_setenv + BSD like PAM environment variable setting + +@@ -17,7 +14,7 @@ + + + +- ++ + #include <security/pam_misc.h> + + int pam_misc_setenv +@@ -29,7 +26,7 @@ + + + +- ++ + DESCRIPTION + + This function performs a task equivalent to +@@ -44,7 +41,7 @@ + + + +- ++ + SEE ALSO + + +@@ -56,7 +53,7 @@ + + + +- ++ + STANDARDS + + The pam_misc_setenv function is part of the +@@ -65,4 +62,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_open_session.3.xml b/doc/man/pam_open_session.3.xml +index eba0bc016..d37b3e595 100644 +--- a/doc/man/pam_open_session.3.xml ++++ b/doc/man/pam_open_session.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_open_session + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_open_session + start PAM session management + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_open_session +@@ -29,7 +26,7 @@ + + + +- ++ + DESCRIPTION + + The pam_open_session function sets up a +@@ -63,7 +60,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -101,7 +98,7 @@ + + + +- ++ + SEE ALSO + + +@@ -112,4 +109,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_prompt.3.xml b/doc/man/pam_prompt.3.xml +index bf0c9bf6b..c65a0c90a 100644 +--- a/doc/man/pam_prompt.3.xml ++++ b/doc/man/pam_prompt.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_prompt + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_prompt + pam_vprompt + interface to conversation function +@@ -18,7 +15,7 @@ + + + +- ++ + + #include <security/pam_ext.h> + +@@ -40,7 +37,7 @@ + + + +- ++ + DESCRIPTION + + The pam_prompt function constructs a message +@@ -52,7 +49,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -91,7 +88,7 @@ + + + +- ++ + SEE ALSO + + +@@ -103,7 +100,7 @@ + + + +- ++ + STANDARDS + + The pam_prompt and pam_vprompt +@@ -111,4 +108,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_putenv.3.xml b/doc/man/pam_putenv.3.xml +index 2d4afbc51..7267046f8 100644 +--- a/doc/man/pam_putenv.3.xml ++++ b/doc/man/pam_putenv.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_putenv + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_putenv + set or change PAM environment variable + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_putenv +@@ -27,7 +25,7 @@ + + + +- ++ + DESCRIPTION + + The pam_putenv function is used to +@@ -83,7 +81,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -129,7 +127,7 @@ + + + +- ++ + SEE ALSO + + +@@ -149,4 +147,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_set_data.3.xml b/doc/man/pam_set_data.3.xml +index c20068c64..2bcfeb0b7 100644 +--- a/doc/man/pam_set_data.3.xml ++++ b/doc/man/pam_set_data.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_set_data + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_set_data + + set module internal data +@@ -22,7 +19,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_set_data +@@ -36,7 +33,7 @@ + + + +- ++ + DESCRIPTION + + The pam_set_data function associates a pointer +@@ -123,7 +120,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -154,7 +151,7 @@ + + + +- ++ + SEE ALSO + + +@@ -169,4 +166,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_set_item.3.xml b/doc/man/pam_set_item.3.xml +index 30ab92b90..1dbaeebfd 100644 +--- a/doc/man/pam_set_item.3.xml ++++ b/doc/man/pam_set_item.3.xml +@@ -1,22 +1,13 @@ +- +- +- +---> +-]> +- +- ++ + + + pam_set_item + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_set_item + + set and update PAM information +@@ -28,7 +19,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_set_item +@@ -41,7 +32,7 @@ + + + +- ++ + DESCRIPTION + + The pam_set_item function allows applications +@@ -52,16 +43,14 @@ + supported: + + +- ++ + + + The following additional items are specific to Linux-PAM and should not be used in + portable applications: + + +- ++ + + + For all item_types, other than PAM_CONV and +@@ -81,7 +70,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -121,7 +110,7 @@ + + + +- ++ + SEE ALSO + + +@@ -133,4 +122,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_setcred.3.xml b/doc/man/pam_setcred.3.xml +index 629224824..09fe30d16 100644 +--- a/doc/man/pam_setcred.3.xml ++++ b/doc/man/pam_setcred.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_setcred + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_setcred + + establish / delete user credentials +@@ -19,7 +16,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_setcred +@@ -30,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_setcred function is used to establish, +@@ -95,7 +92,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -160,7 +157,7 @@ + + + +- ++ + SEE ALSO + + +@@ -177,4 +174,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_acct_mgmt.3.xml b/doc/man/pam_sm_acct_mgmt.3.xml +index b37dc3069..822a338ad 100644 +--- a/doc/man/pam_sm_acct_mgmt.3.xml ++++ b/doc/man/pam_sm_acct_mgmt.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_acct_mgmt + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_acct_mgmt + PAM service function for account management + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_acct_mgmt +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_acct_mgmt function is the service +@@ -64,7 +62,7 @@ + PAM_DISALLOW_NULL_AUTHTOK + + +- Return PAM_AUTH_ERR if the ++ Return PAM_AUTH_ERR if the + database of authentication tokens for this authentication + mechanism has a NULL entry for the user. + +@@ -73,7 +71,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -131,7 +129,7 @@ + + + +- ++ + SEE ALSO + + +@@ -151,4 +149,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_authenticate.3.xml b/doc/man/pam_sm_authenticate.3.xml +index ef3a8f150..ec3de2fdf 100644 +--- a/doc/man/pam_sm_authenticate.3.xml ++++ b/doc/man/pam_sm_authenticate.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_authenticate + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_authenticate + PAM service function for user authentication + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_authenticate +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_authenticate function is the service +@@ -58,7 +56,7 @@ + PAM_DISALLOW_NULL_AUTHTOK + + +- Return PAM_AUTH_ERR if the ++ Return PAM_AUTH_ERR if the + database of authentication tokens for this authentication + mechanism has a NULL entry for the user. + Without this flag, such a NULL token +@@ -69,7 +67,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -128,7 +126,7 @@ + + + +- ++ + SEE ALSO + + +@@ -148,4 +146,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_chauthtok.3.xml b/doc/man/pam_sm_chauthtok.3.xml +index 25e17d020..692bc620d 100644 +--- a/doc/man/pam_sm_chauthtok.3.xml ++++ b/doc/man/pam_sm_chauthtok.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_chauthtok + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_chauthtok + PAM service function for authentication token management + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_chauthtok +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_chauthtok function is the service +@@ -77,7 +75,7 @@ + some network it should attempt to verify it can connect to + this system on receiving this flag. If a module cannot establish + it is ready to update the user's authentication token it should +- return PAM_TRY_AGAIN, this ++ return PAM_TRY_AGAIN, this + information will be passed back to the application. + + +@@ -93,7 +91,7 @@ + + This informs the module that this is the call it should change + the authorization tokens. If the flag is logically OR'd with +- PAM_CHANGE_EXPIRED_AUTHTOK, the ++ PAM_CHANGE_EXPIRED_AUTHTOK, the + token is only changed if it has actually expired. + + +@@ -101,15 +99,15 @@ + + + The PAM library calls this function twice in succession. The first +- time with PAM_PRELIM_CHECK and then, ++ time with PAM_PRELIM_CHECK and then, + if the module does not return +- PAM_TRY_AGAIN, subsequently with +- PAM_UPDATE_AUTHTOK. It is only on ++ PAM_TRY_AGAIN, subsequently with ++ PAM_UPDATE_AUTHTOK. It is only on + the second call that the authorization token is (possibly) changed. + + + +- ++ + RETURN VALUES + + +@@ -181,7 +179,7 @@ + + + +- ++ + SEE ALSO + + +@@ -201,4 +199,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_close_session.3.xml b/doc/man/pam_sm_close_session.3.xml +index 6d8278ec7..e76693fd9 100644 +--- a/doc/man/pam_sm_close_session.3.xml ++++ b/doc/man/pam_sm_close_session.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_close_session + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_close_session + PAM service function to terminate session management + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_close_session +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_close_session function is the service +@@ -40,7 +38,7 @@ + + + This function is called to terminate a session. The only valid +- value for flags is zero or: ++ value for flags is zero or: + + + +@@ -54,7 +52,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -76,7 +74,7 @@ + + + +- ++ + SEE ALSO + + +@@ -96,4 +94,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_open_session.3.xml b/doc/man/pam_sm_open_session.3.xml +index ead7ca770..392225a4a 100644 +--- a/doc/man/pam_sm_open_session.3.xml ++++ b/doc/man/pam_sm_open_session.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_open_session + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_open_session + PAM service function to start session management + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_open_session +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_open_session function is the service +@@ -40,7 +38,7 @@ + + + This function is called to commence a session. The only valid +- value for flags is zero or: ++ value for flags is zero or: + + + +@@ -54,7 +52,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -76,7 +74,7 @@ + + + +- ++ + SEE ALSO + + +@@ -96,4 +94,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_sm_setcred.3.xml b/doc/man/pam_sm_setcred.3.xml +index bb04a2df3..93a69e3e3 100644 +--- a/doc/man/pam_sm_setcred.3.xml ++++ b/doc/man/pam_sm_setcred.3.xml +@@ -1,14 +1,12 @@ +- +- +- ++ + + pam_sm_setcred + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sm_setcred + PAM service function to alter credentials + +@@ -16,7 +14,7 @@ + + + +- ++ + #include <security/pam_modules.h> + + int pam_sm_setcred +@@ -29,7 +27,7 @@ + + + +- ++ + DESCRIPTION + + The pam_sm_setcred function is the service +@@ -92,7 +90,7 @@ + + + +- The way the auth stack is ++ The way the auth stack is + navigated in order to evaluate the pam_setcred() + function call, independent of the pam_sm_setcred() + return codes, is exactly the same way that it was navigated when +@@ -102,11 +100,11 @@ + libpam evaluates the pam_setcred() function + call. Otherwise, the return codes from each module specific + pam_sm_setcred() call are treated as +- required. ++ required. + + + +- ++ + RETURN VALUES + + +@@ -158,7 +156,7 @@ + + + +- ++ + SEE ALSO + + +@@ -181,4 +179,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_start.3.xml b/doc/man/pam_start.3.xml +index 1d544e641..470c6cec1 100644 +--- a/doc/man/pam_start.3.xml ++++ b/doc/man/pam_start.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_start + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_start + pam_start_confdir + initialization of PAM transaction +@@ -19,7 +16,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + int pam_start +@@ -40,7 +37,7 @@ + + + +- ++ + DESCRIPTION + + The pam_start function creates the PAM context +@@ -108,7 +105,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -147,7 +144,7 @@ + + + +- ++ + SEE ALSO + + +@@ -164,4 +161,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_strerror.3.xml b/doc/man/pam_strerror.3.xml +index 954e131d5..b76cbc4d1 100644 +--- a/doc/man/pam_strerror.3.xml ++++ b/doc/man/pam_strerror.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_strerror + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_strerror + return string describing PAM error code + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + const char *pam_strerror +@@ -29,7 +26,7 @@ + + + +- ++ + DESCRIPTION + + The pam_strerror function returns a pointer to +@@ -40,14 +37,14 @@ + modify this string. + + +- ++ + RETURN VALUES + + This function returns always a pointer to a string. + + + +- ++ + SEE ALSO + + +@@ -55,4 +52,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_syslog.3.xml b/doc/man/pam_syslog.3.xml +index ca28587ef..f5be287fe 100644 +--- a/doc/man/pam_syslog.3.xml ++++ b/doc/man/pam_syslog.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_syslog + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_syslog + pam_vsyslog + send messages to the system logger +@@ -18,7 +15,7 @@ + + + +- ++ + + #include <syslog.h> + #include <security/pam_ext.h> +@@ -39,7 +36,7 @@ + + + +- ++ + DESCRIPTION + + The pam_syslog function logs messages using +@@ -62,7 +59,7 @@ + + + +- ++ + SEE ALSO + + +@@ -71,7 +68,7 @@ + + + +- ++ + STANDARDS + + The pam_syslog and pam_vsyslog +@@ -79,4 +76,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/doc/man/pam_xauth_data.3.xml b/doc/man/pam_xauth_data.3.xml +index 505985e49..447a9c2d4 100644 +--- a/doc/man/pam_xauth_data.3.xml ++++ b/doc/man/pam_xauth_data.3.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_xauth_data + 3 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_xauth_data + structure containing X authentication data + +@@ -18,7 +15,7 @@ + + + +- ++ + #include <security/pam_appl.h> + + +@@ -31,7 +28,7 @@ struct pam_xauth_data { + + + +- ++ + DESCRIPTION + + The pam_xauth_data structure contains X +@@ -70,7 +67,7 @@ struct pam_xauth_data { + + + +- ++ + SEE ALSO + + +@@ -82,7 +79,7 @@ struct pam_xauth_data { + + + +- ++ + STANDARDS + + The pam_xauth_data structure and +@@ -91,4 +88,4 @@ struct pam_xauth_data { + + + +- ++ +\ No newline at end of file +diff --git a/doc/mwg/Linux-PAM_MWG.xml b/doc/mwg/Linux-PAM_MWG.xml +index 3022538c0..046c3c480 100644 +--- a/doc/mwg/Linux-PAM_MWG.xml ++++ b/doc/mwg/Linux-PAM_MWG.xml +@@ -1,49 +1,38 @@ +- +- +- +- ++ ++ + The Linux-PAM Module Writers' Guide + +- +- Andrew G. +- Morgan +- morgan@kernel.org +- +- +- Thorsten +- Kukuk +- kukuk@thkukuk.de +- ++ Andrew G.Morganmorgan@kernel.org ++ ThorstenKukukkukuk@thkukuk.de + + Version 1.1.2, 31. August 2010 + + + This manual documents what a programmer needs to know in order + to write a module that conforms to the +- Linux-PAM standard.It also ++ Linux-PAM standard.It also + discusses some security issues from the point of view of the + module programmer. + + +- ++ + +- ++ + Introduction +-
++
+ Description + +- Linux-PAM (Pluggable Authentication ++ Linux-PAM (Pluggable Authentication + Modules for Linux) is a library that enables the local system + administrator to choose how individual applications authenticate + users. For an overview of the +- Linux-PAM library see the ++ Linux-PAM library see the + Linux-PAM System Administrators' Guide. + + +- A Linux-PAM module is a single ++ A Linux-PAM module is a single + executable binary file that can be loaded by the +- Linux-PAM interface library. ++ Linux-PAM interface library. + This PAM library is configured locally with a system file, + /etc/pam.conf, to authenticate a user + request via the locally available authentication modules. The +@@ -54,14 +43,14 @@ + + dlopen3 + . Alternatively, the modules can be statically +- linked into the Linux-PAM library; +- this is mostly to allow Linux-PAM to ++ linked into the Linux-PAM library; ++ this is mostly to allow Linux-PAM to + be used on platforms without dynamic linking available, but this is + a deprecated functionality. It is the +- Linux-PAM interface that is called ++ Linux-PAM interface that is called + by an application and it is the responsibility of the library to + locate, load and call the appropriate functions in a +- Linux-PAM-module. ++ Linux-PAM-module. + + + Except for the immediate purpose of interacting with the user +@@ -71,7 +60,7 @@ + +
+ +-
++
+ Synopsis + + #include <security/pam_modules.h> +@@ -82,63 +71,52 @@ gcc -shared -o pam_module.so pam_module.o -lpam +
+ + +- ++ + What can be expected by the module + + Here we list the interface that the conventions that all +- Linux-PAM modules must adhere to. ++ Linux-PAM modules must adhere to. + +-
++
+ + Getting and setting <emphasis>PAM_ITEM</emphasis>s and + <emphasis>data</emphasis> + + + First, we cover what the module should expect from the +- Linux-PAM library and a +- Linux-PAM aware application. ++ Linux-PAM library and a ++ Linux-PAM aware application. + Essentially this is the libpam.* library. + +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ +
+-
++
+ + Other functions provided by <filename>libpam</filename> + +- +- ++ ++ +
+ + +- ++ + What is expected of a module + + The module must supply a sub-set of the six functions listed + below. Together they define the function of a +- Linux-PAM module. Module developers ++ Linux-PAM module. Module developers + are strongly urged to read the comments on security that follow + this list. + +-
++
+ Overview + + The six module functions are grouped into four independent +@@ -149,7 +127,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + at least one of these groups. A single module may contain the + necessary functions for all four groups. + +-
++
+ Functional independence + + The independence of the four groups of service a module can +@@ -163,7 +141,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + As an informative example, consider the possibility that an + application applies to change a user's authentication token, + without having first requested that +- Linux-PAM authenticate the ++ Linux-PAM authenticate the + user. In some cases this may be deemed appropriate: when + root wants to change the authentication + token of some lesser user. In other cases it may not be +@@ -176,7 +154,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + this when implementing a given module. + +
+-
++
+ Minimizing administration problems + + To avoid system administration problems and the poor +@@ -189,7 +167,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + simply return PAM_IGNORE. + +
+-
++
+ Arguments supplied to the module + + The flags argument of each of +@@ -203,7 +181,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + arguments are taken from the line appropriate to this + module---that is, with the service_name + matching that of the application---in the configuration file +- (see the Linux-PAM ++ (see the Linux-PAM + System Administrators' Guide). Together these two parameters + provide the number of arguments and an array of pointers to + the individual argument tokens. This will be familiar to C +@@ -214,33 +192,27 @@ gcc -shared -o pam_module.so pam_module.o -lpam + +
+
+-
++
+ Authentication management +- +- ++ ++ +
+-
++
+ Account management +- ++ +
+-
++
+ Session management +- +- ++ ++ +
+-
++
+ Authentication token management +- ++ +
+ + +- ++ + Generic optional arguments + + Here we list the generic arguments that all modules can expect to +@@ -276,17 +248,17 @@ gcc -shared -o pam_module.so pam_module.o -lpam + + + +- ++ + Programming notes + + Here we collect some pointers for the module writer to bear in mind +- when writing/developing a Linux-PAM ++ when writing/developing a Linux-PAM + compatible module. + + +-
++
+ Security issues for module creation +-
++
+ Sufficient resources + + Care should be taken to ensure that the proper execution +@@ -299,7 +271,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + consideration. + +
+-
++
+ Who´s who? + + Generally, the module may wish to establish the identity of +@@ -349,13 +321,13 @@ gcc -shared -o pam_module.so pam_module.o -lpam + Z, the user under whose identity the service will be granted. + This is the username returned by + pam_get_user() and also stored in the +- Linux-PAM item, ++ Linux-PAM item, + PAM_USER. + + + + +- Linux-PAM has a place for ++ Linux-PAM has a place for + an additional user identity that a module may care to make + use of. This is the PAM_RUSER item. + Generally, network sensitive modules/applications may wish +@@ -369,10 +341,10 @@ gcc -shared -o pam_module.so pam_module.o -lpam + uid or euid of the + running process, it should take care to restore the original + values prior to returning control to the +- Linux-PAM library. ++ Linux-PAM library. + +
+-
++
+ Using the conversation function + + Prior to calling the conversation function, the module should +@@ -389,7 +361,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + indicating failure. + +
+-
++
+ Authentication tokens + + To ensure that the authentication tokens are not left lying +@@ -403,7 +375,7 @@ gcc -shared -o pam_module.so pam_module.o -lpam + general rule the module should overwrite authentication tokens + as soon as they are no longer needed. Especially before + free()'ing them. The +- Linux-PAM library is ++ Linux-PAM library is + required to do this when either of these authentication + token items are (re)set. + +@@ -437,7 +409,7 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) + +
+
+-
++
+ Use of <citerefentry> + <refentrytitle>syslog</refentrytitle><manvolnum>3</manvolnum> + </citerefentry> +@@ -451,7 +423,7 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) + + syslog3 + with facility-type +- LOG_AUTHPRIV. ++ LOG_AUTHPRIV. + + + With a few exceptions, the level of logging is, at the discretion +@@ -501,7 +473,7 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) + + +
+-
++
+ Modules that require system libraries + + Writing a module is much like writing an application. You +@@ -526,16 +498,16 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) +
+ + +- ++ + An example module + + At some point, we may include a fully commented example of a module in + this document. For now, please look at the modules directory of the +- Linux-PAM sources. ++ Linux-PAM sources. + + + +- ++ + See also + + +@@ -558,7 +530,7 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) + + + +- ++ + Author/acknowledgments + + This document was written by Andrew G. Morgan (morgan@kernel.org) +@@ -578,14 +550,14 @@ int cleanup(pam_handle_t *pamh, void *data, int error_status) + + Thanks are also due to Sun Microsystems, especially to Vipin Samar and + Charlie Lai for their advice. At an early stage in the development of +- Linux-PAM, Sun graciously made the ++ Linux-PAM, Sun graciously made the + documentation for their implementation of PAM available. This act + greatly accelerated the development of +- Linux-PAM. ++ Linux-PAM. + + + +- ++ + Copyright information for this document + + Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> +@@ -629,4 +601,4 @@ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + + +- ++ +\ No newline at end of file +diff --git a/doc/mwg/Makefile.am b/doc/mwg/Makefile.am +index 688e6cb3a..340249c6c 100644 +--- a/doc/mwg/Makefile.am ++++ b/doc/mwg/Makefile.am +@@ -16,7 +16,7 @@ all: Linux-PAM_MWG.txt html/Linux-PAM_MWG.html Linux-PAM_MWG.pdf + + Linux-PAM_MWG.pdf: $(XMLS) $(DEP_XMLS) + if ENABLE_GENERATE_PDF +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -28,7 +28,7 @@ else + endif + + Linux-PAM_MWG.txt: $(XMLS) $(DEP_XMLS) +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -37,7 +37,7 @@ Linux-PAM_MWG.txt: $(XMLS) $(DEP_XMLS) + + html/Linux-PAM_MWG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam base.dir html/ \ + --stringparam root.filename Linux-PAM_MWG \ + --stringparam use.id.as.filename 1 \ +diff --git a/doc/mwg/pam_conv.xml b/doc/mwg/pam_conv.xml +index a2b470af5..2b369503d 100644 +--- a/doc/mwg/pam_conv.xml ++++ b/doc/mwg/pam_conv.xml +@@ -1,11 +1,7 @@ +- +- +-
++
+ The conversation function + +- ++ + + + struct pam_message { +@@ -24,12 +20,10 @@ struct pam_conv { + void *appdata_ptr; + }; + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_fail_delay.xml b/doc/mwg/pam_fail_delay.xml +index 589e1148b..d602a1f79 100644 +--- a/doc/mwg/pam_fail_delay.xml ++++ b/doc/mwg/pam_fail_delay.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Request a delay on failure + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_get_data.xml b/doc/mwg/pam_get_data.xml +index b1afdb3f7..e1342d16e 100644 +--- a/doc/mwg/pam_get_data.xml ++++ b/doc/mwg/pam_get_data.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Get module internal data + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_get_item.xml b/doc/mwg/pam_get_item.xml +index 370a10a1a..e0635d212 100644 +--- a/doc/mwg/pam_get_item.xml ++++ b/doc/mwg/pam_get_item.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Getting PAM items + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_get_user.xml b/doc/mwg/pam_get_user.xml +index 1cb7fdf30..3b79fe076 100644 +--- a/doc/mwg/pam_get_user.xml ++++ b/doc/mwg/pam_get_user.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Get user name + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_getenv.xml b/doc/mwg/pam_getenv.xml +index 61d69c33c..f7b483ed9 100644 +--- a/doc/mwg/pam_getenv.xml ++++ b/doc/mwg/pam_getenv.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Get a PAM environment variable + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_getenvlist.xml b/doc/mwg/pam_getenvlist.xml +index d3c2fcd35..4433c04d6 100644 +--- a/doc/mwg/pam_getenvlist.xml ++++ b/doc/mwg/pam_getenvlist.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Getting the PAM environment + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_putenv.xml b/doc/mwg/pam_putenv.xml +index e55f1a42f..6378a15b2 100644 +--- a/doc/mwg/pam_putenv.xml ++++ b/doc/mwg/pam_putenv.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Set or change PAM environment variable + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_set_data.xml b/doc/mwg/pam_set_data.xml +index 18b2711b9..3fb3b1fed 100644 +--- a/doc/mwg/pam_set_data.xml ++++ b/doc/mwg/pam_set_data.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Set module internal data + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_set_item.xml b/doc/mwg/pam_set_item.xml +index 7d19925e0..7a8ee8dea 100644 +--- a/doc/mwg/pam_set_item.xml ++++ b/doc/mwg/pam_set_item.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Setting PAM items + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_acct_mgmt.xml b/doc/mwg/pam_sm_acct_mgmt.xml +index 10b3c9e9e..c17a9bf06 100644 +--- a/doc/mwg/pam_sm_acct_mgmt.xml ++++ b/doc/mwg/pam_sm_acct_mgmt.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function for account management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_authenticate.xml b/doc/mwg/pam_sm_authenticate.xml +index 54c79af6f..138fc1ff7 100644 +--- a/doc/mwg/pam_sm_authenticate.xml ++++ b/doc/mwg/pam_sm_authenticate.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function for user authentication + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_chauthtok.xml b/doc/mwg/pam_sm_chauthtok.xml +index a13643158..546ae6622 100644 +--- a/doc/mwg/pam_sm_chauthtok.xml ++++ b/doc/mwg/pam_sm_chauthtok.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function to alter authentication token + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_close_session.xml b/doc/mwg/pam_sm_close_session.xml +index 9346c506b..69140b810 100644 +--- a/doc/mwg/pam_sm_close_session.xml ++++ b/doc/mwg/pam_sm_close_session.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function to terminate session management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_open_session.xml b/doc/mwg/pam_sm_open_session.xml +index b8e3fa90f..aba28a3e9 100644 +--- a/doc/mwg/pam_sm_open_session.xml ++++ b/doc/mwg/pam_sm_open_session.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function to start session management + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_sm_setcred.xml b/doc/mwg/pam_sm_setcred.xml +index eee8e1d61..36e43c04b 100644 +--- a/doc/mwg/pam_sm_setcred.xml ++++ b/doc/mwg/pam_sm_setcred.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Service function to alter credentials + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/mwg/pam_strerror.xml b/doc/mwg/pam_strerror.xml +index 35b08a274..e4e1c56af 100644 +--- a/doc/mwg/pam_strerror.xml ++++ b/doc/mwg/pam_strerror.xml +@@ -1,18 +1,12 @@ +- +- +-
++
+ Strings describing PAM error codes + +- ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/Linux-PAM_SAG.xml b/doc/sag/Linux-PAM_SAG.xml +index 2adaef7da..952f224b4 100644 +--- a/doc/sag/Linux-PAM_SAG.xml ++++ b/doc/sag/Linux-PAM_SAG.xml +@@ -1,36 +1,25 @@ +- +- +- +- ++ ++ + The Linux-PAM System Administrators' Guide + +- +- Andrew G. +- Morgan +- morgan@kernel.org +- +- +- Thorsten +- Kukuk +- kukuk@thkukuk.de +- ++ Andrew G.Morganmorgan@kernel.org ++ ThorstenKukukkukuk@thkukuk.de + + Version 1.1.2, 31. August 2010 + + + This manual documents what a system-administrator needs to know about +- the Linux-PAM library. It covers the ++ the Linux-PAM library. It covers the + correct syntax of the PAM configuration file and discusses strategies + for maintaining a secure system. + + +- ++ + +- ++ + Introduction + +- Linux-PAM (Pluggable Authentication ++ Linux-PAM (Pluggable Authentication + Modules for Linux) is a suite of shared libraries that enable the + local system administrator to choose how applications authenticate users. + +@@ -58,7 +47,7 @@ + on entries in the /etc/group file. + + +- It is the purpose of the Linux-PAM ++ It is the purpose of the Linux-PAM + project to separate the development of privilege granting software + from the development of secure and appropriate authentication schemes. + This is accomplished by providing a library of functions that an +@@ -76,7 +65,7 @@ + + + +- ++ + Some comments on the text + + Before proceeding to read the rest of this document, it should be +@@ -91,7 +80,7 @@ + + As an example of the above, where it is explicit, the text assumes + that PAM loadable object files (the +- modules) are to be located in ++ modules) are to be located in + the following directory: /lib/security/ or + /lib64/security depending on the architecture. + This is generally the location that seems to be compatible with the +@@ -103,7 +92,7 @@ + + + +- ++ + Overview + + For the uninitiated, we begin by considering an example. We take an +@@ -121,16 +110,16 @@ + password and then verifying that it agrees with that located on + the system; hence verifying that as far as the system is concerned + the user is who they claim to be. This is the task that is delegated +- to Linux-PAM. ++ to Linux-PAM. + + + From the perspective of the application programmer (in this case + the person that wrote the login application), +- Linux-PAM takes care of this ++ Linux-PAM takes care of this + authentication task -- verifying the identity of the user. + + +- The flexibility of Linux-PAM is ++ The flexibility of Linux-PAM is + that you, the system administrator, have + the freedom to stipulate which authentication scheme is to be + used. You have the freedom to set the scheme for any/all +@@ -152,7 +141,7 @@ + authentication can be upgraded to include (long) division! + + +- Linux-PAM deals with four ++ Linux-PAM deals with four + separate types of (management) task. These are: + authentication management; + account management; +@@ -160,15 +149,15 @@ + password management. + The association of the preferred management scheme with the behavior + of an application is made with entries in the relevant +- Linux-PAM configuration file. ++ Linux-PAM configuration file. + The management functions are performed by modules + specified in the configuration file. The syntax for this + file is discussed in the section +- below. ++ below. + + + Here is a figure that describes the overall organization of +- Linux-PAM: ++ Linux-PAM: + + +----------------+ + | application: X | +@@ -193,14 +182,14 @@ + + By way of explanation, the left of the figure represents the + application; application X. Such an application interfaces with the +- Linux-PAM library and knows none of ++ Linux-PAM library and knows none of + the specifics of its configured authentication method. The +- Linux-PAM library (in the center) ++ Linux-PAM library (in the center) + consults the contents of the PAM configuration file and loads the + modules that are appropriate for application-X. These modules fall + into one of four management groups (lower-center) and are stacked in + the order they appear in the configuration file. These modules, when +- called by Linux-PAM, perform the ++ called by Linux-PAM, perform the + various authentication tasks for the application. Textual information, + required from/or offered to the user, can be exchanged through the + use of the application-supplied conversation +@@ -216,34 +205,28 @@ + + + +- ++ + The Linux-PAM configuration file +- +-
++ ++
+ Configuration file syntax +- ++ +
+-
++
+ Directory based configuration +- ++ +
+-
++
+ Example configuration file entries + + In this section, we give some examples of entries that can +- be present in the Linux-PAM ++ be present in the Linux-PAM + configuration file. As a first attempt at configuring your + system you could do worse than to implement these. + + + If a system is to be considered secure, it had better have a +- reasonably secure 'other entry. ++ reasonably secure 'other entry. + The following is a paranoid setting (which is not a bad place + to start!): + +@@ -311,7 +294,7 @@ session required pam_deny.so + + On a less sensitive computer, one on which the system + administrator wishes to remain ignorant of much of the +- power of Linux-PAM, the ++ power of Linux-PAM, the + following selection of lines (in + /etc/pam.d/other) is likely to + mimic the historically familiar Linux setup. +@@ -331,21 +314,21 @@ session required pam_unix.so +
+ + +- ++ + Security issues +-
++
+ If something goes wrong + +- Linux-PAM has the potential ++ Linux-PAM has the potential + to seriously change the security of your system. You can + choose to have no security or absolute security (no access +- permitted). In general, Linux-PAM ++ permitted). In general, Linux-PAM + errs towards the latter. Any number of configuration errors + can disable access to your system partially, or completely. + + + The most dramatic problem that is likely to be encountered when +- configuring Linux-PAM is that of ++ configuring Linux-PAM is that of + deleting the configuration file(s): + /etc/pam.d/* and/or + /etc/pam.conf. This will lock you out of +@@ -357,11 +340,11 @@ session required pam_unix.so + things from there. + +
+-
++
+ Avoid having a weak `other' configuration + + It is not a good thing to have a weak default +- (other) entry. ++ (other) entry. + This service is the default configuration for all PAM aware + applications and if it is weak, your system is likely to be + vulnerable to attack. +@@ -388,93 +371,57 @@ session required pam_warn.so +
+ + +- ++ + A reference guide for available modules + + Here, we collect together the descriptions of the various modules + coming with Linux-PAM. + +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- +- ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ + + +- ++ + See also + + +@@ -497,7 +444,7 @@ session required pam_warn.so + + + +- ++ + Author/acknowledgments + + This document was written by Andrew G. Morgan (morgan@kernel.org) +@@ -518,14 +465,14 @@ session required pam_warn.so + + Thanks are also due to Sun Microsystems, especially to Vipin Samar and + Charlie Lai for their advice. At an early stage in the development of +- Linux-PAM, Sun graciously made the ++ Linux-PAM, Sun graciously made the + documentation for their implementation of PAM available. This act + greatly accelerated the development of +- Linux-PAM. ++ Linux-PAM. + + + +- ++ + Copyright information for this document + + Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> +@@ -569,4 +516,4 @@ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE + USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + + +- ++ +\ No newline at end of file +diff --git a/doc/sag/Makefile.am b/doc/sag/Makefile.am +index 84fd383fe..04c90919e 100644 +--- a/doc/sag/Makefile.am ++++ b/doc/sag/Makefile.am +@@ -7,7 +7,6 @@ CLEANFILES = Linux-PAM_SAG.fo *~ + EXTRA_DIST = $(XMLS) + + XMLS = Linux-PAM_SAG.xml $(shell ls $(srcdir)/pam_*.xml) +- + DEP_XMLS = $(shell ls $(top_srcdir)/modules/pam_*/pam_*.xml) + + if ENABLE_REGENERATE_MAN +@@ -17,7 +16,7 @@ all: Linux-PAM_SAG.txt html/Linux-PAM_SAG.html Linux-PAM_SAG.pdf + + Linux-PAM_SAG.pdf: $(XMLS) $(DEP_XMLS) + if ENABLE_GENERATE_PDF +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -29,7 +28,7 @@ else + endif + + Linux-PAM_SAG.txt: $(XMLS) $(DEP_XMLS) +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam generate.toc "book toc" \ + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ +@@ -38,7 +37,7 @@ Linux-PAM_SAG.txt: $(XMLS) $(DEP_XMLS) + + html/Linux-PAM_SAG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +- $(XMLLINT) --nonet --xinclude --postvalid --noent --noout $< ++ $(XMLLINT) --nonet --xinclude --relaxng $(DOCBOOK_RNG) --noent --noout $< + $(XSLTPROC) --stringparam base.dir html/ \ + --stringparam root.filename Linux-PAM_SAG \ + --stringparam use.id.as.filename 1 \ +diff --git a/doc/sag/pam_access.xml b/doc/sag/pam_access.xml +index b9bf39d0a..75f14b37a 100644 +--- a/doc/sag/pam_access.xml ++++ b/doc/sag/pam_access.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_access - logdaemon style login access control +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_debug.xml b/doc/sag/pam_debug.xml +index b131954c1..0c8aa940d 100644 +--- a/doc/sag/pam_debug.xml ++++ b/doc/sag/pam_debug.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_debug - debug the PAM stack +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_deny.xml b/doc/sag/pam_deny.xml +index 2cb71a03f..fdd2aaae7 100644 +--- a/doc/sag/pam_deny.xml ++++ b/doc/sag/pam_deny.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_deny - locking-out PAM module +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_echo.xml b/doc/sag/pam_echo.xml +index b066d4acc..e4de88627 100644 +--- a/doc/sag/pam_echo.xml ++++ b/doc/sag/pam_echo.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_echo - print text messages +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_env.xml b/doc/sag/pam_env.xml +index 9f6e63319..68b7c4f0c 100644 +--- a/doc/sag/pam_env.xml ++++ b/doc/sag/pam_env.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_env - set/unset environment variables +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_exec.xml b/doc/sag/pam_exec.xml +index 265e7f415..859bb3b92 100644 +--- a/doc/sag/pam_exec.xml ++++ b/doc/sag/pam_exec.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_exec - call an external command +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_faildelay.xml b/doc/sag/pam_faildelay.xml +index 1d8295e01..969020878 100644 +--- a/doc/sag/pam_faildelay.xml ++++ b/doc/sag/pam_faildelay.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_faildelay - change the delay on failure per-application +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_faillock.xml b/doc/sag/pam_faillock.xml +index 96940c6bf..32777b1d3 100644 +--- a/doc/sag/pam_faillock.xml ++++ b/doc/sag/pam_faillock.xml +@@ -1,38 +1,27 @@ +- +- +-
++
+ pam_faillock - temporarily locking access based on failed authentication attempts during an interval +- +- ++ ++ + +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_filter.xml b/doc/sag/pam_filter.xml +index 6a4a1ba22..56af28cb7 100644 +--- a/doc/sag/pam_filter.xml ++++ b/doc/sag/pam_filter.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_filter - filter module +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_ftp.xml b/doc/sag/pam_ftp.xml +index b24562659..13fe40a0f 100644 +--- a/doc/sag/pam_ftp.xml ++++ b/doc/sag/pam_ftp.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_ftp - module for anonymous access +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_group.xml b/doc/sag/pam_group.xml +index ce82bf0f0..e4efc0356 100644 +--- a/doc/sag/pam_group.xml ++++ b/doc/sag/pam_group.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_group - module to modify group access +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_issue.xml b/doc/sag/pam_issue.xml +index 5033d23f6..f56cc4632 100644 +--- a/doc/sag/pam_issue.xml ++++ b/doc/sag/pam_issue.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_issue - add issue file to user prompt +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_keyinit.xml b/doc/sag/pam_keyinit.xml +index 3caa4c270..d8013512a 100644 +--- a/doc/sag/pam_keyinit.xml ++++ b/doc/sag/pam_keyinit.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_keyinit - display the keyinit file +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_lastlog.xml b/doc/sag/pam_lastlog.xml +index c250c0189..1c9c6b2c1 100644 +--- a/doc/sag/pam_lastlog.xml ++++ b/doc/sag/pam_lastlog.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_lastlog - display date of last login +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_limits.xml b/doc/sag/pam_limits.xml +index 7f898a406..f03a1e41e 100644 +--- a/doc/sag/pam_limits.xml ++++ b/doc/sag/pam_limits.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_limits - limit resources +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_listfile.xml b/doc/sag/pam_listfile.xml +index db7acdc61..66d7a82ef 100644 +--- a/doc/sag/pam_listfile.xml ++++ b/doc/sag/pam_listfile.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_listfile - deny or allow services based on an arbitrary file +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_localuser.xml b/doc/sag/pam_localuser.xml +index 480ff96ec..a3cee75f7 100644 +--- a/doc/sag/pam_localuser.xml ++++ b/doc/sag/pam_localuser.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_localuser - require users to be listed in /etc/passwd +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_loginuid.xml b/doc/sag/pam_loginuid.xml +index 3b4428434..fc4a09674 100644 +--- a/doc/sag/pam_loginuid.xml ++++ b/doc/sag/pam_loginuid.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_loginuid - record user's login uid to the process attribute +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_mail.xml b/doc/sag/pam_mail.xml +index 031f786d4..6b76770e8 100644 +--- a/doc/sag/pam_mail.xml ++++ b/doc/sag/pam_mail.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_mail - inform about available mail +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_mkhomedir.xml b/doc/sag/pam_mkhomedir.xml +index dc6a1eb79..141395cda 100644 +--- a/doc/sag/pam_mkhomedir.xml ++++ b/doc/sag/pam_mkhomedir.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_mkhomedir - create users home directory +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_motd.xml b/doc/sag/pam_motd.xml +index 7a7d2deec..9af77bb53 100644 +--- a/doc/sag/pam_motd.xml ++++ b/doc/sag/pam_motd.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_motd - display the motd file +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_namespace.xml b/doc/sag/pam_namespace.xml +index 6ece9bc14..e18bc0f74 100644 +--- a/doc/sag/pam_namespace.xml ++++ b/doc/sag/pam_namespace.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_namespace - setup a private namespace +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_nologin.xml b/doc/sag/pam_nologin.xml +index 0c626b82c..f2acf4923 100644 +--- a/doc/sag/pam_nologin.xml ++++ b/doc/sag/pam_nologin.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_nologin - prevent non-root users from login +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_permit.xml b/doc/sag/pam_permit.xml +index 7c200478a..52548c0d3 100644 +--- a/doc/sag/pam_permit.xml ++++ b/doc/sag/pam_permit.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_permit - the promiscuous module +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_pwhistory.xml b/doc/sag/pam_pwhistory.xml +index 0677eae39..867a1bca4 100644 +--- a/doc/sag/pam_pwhistory.xml ++++ b/doc/sag/pam_pwhistory.xml +@@ -1,38 +1,27 @@ +- +- +-
++
+ pam_pwhistory - grant access using .pwhistory file +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_rhosts.xml b/doc/sag/pam_rhosts.xml +index 680a70c16..f70b1fbfa 100644 +--- a/doc/sag/pam_rhosts.xml ++++ b/doc/sag/pam_rhosts.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_rhosts - grant access using .rhosts file +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_rootok.xml b/doc/sag/pam_rootok.xml +index 59c99ae92..ab4b4438d 100644 +--- a/doc/sag/pam_rootok.xml ++++ b/doc/sag/pam_rootok.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_rootok - gain only root access +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_securetty.xml b/doc/sag/pam_securetty.xml +index 6ed13e593..9bd9fe218 100644 +--- a/doc/sag/pam_securetty.xml ++++ b/doc/sag/pam_securetty.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_securetty - limit root login to special devices +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_selinux.xml b/doc/sag/pam_selinux.xml +index 9a4f9878f..cb64bcfeb 100644 +--- a/doc/sag/pam_selinux.xml ++++ b/doc/sag/pam_selinux.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_selinux - set the default security context +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_sepermit.xml b/doc/sag/pam_sepermit.xml +index 9831a13f1..264266155 100644 +--- a/doc/sag/pam_sepermit.xml ++++ b/doc/sag/pam_sepermit.xml +@@ -1,38 +1,27 @@ +- +- +-
++
+ pam_sepermit - allow/reject access based on SELinux mode +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_setquota.xml b/doc/sag/pam_setquota.xml +index 368dfd8e2..01d187327 100644 +--- a/doc/sag/pam_setquota.xml ++++ b/doc/sag/pam_setquota.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_setquota - set or modify disk quotas on session start +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_shells.xml b/doc/sag/pam_shells.xml +index b3b3d3273..6765a1973 100644 +--- a/doc/sag/pam_shells.xml ++++ b/doc/sag/pam_shells.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_shells - check for valid login shell +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_succeed_if.xml b/doc/sag/pam_succeed_if.xml +index ce0792d95..7c9f4934c 100644 +--- a/doc/sag/pam_succeed_if.xml ++++ b/doc/sag/pam_succeed_if.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_succeed_if - test account characteristics +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_time.xml b/doc/sag/pam_time.xml +index 74e9e02ab..e15d20a0a 100644 +--- a/doc/sag/pam_time.xml ++++ b/doc/sag/pam_time.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_time - time controlled access +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_timestamp.xml b/doc/sag/pam_timestamp.xml +index 833a6bac9..dfe87e7df 100644 +--- a/doc/sag/pam_timestamp.xml ++++ b/doc/sag/pam_timestamp.xml +@@ -1,42 +1,30 @@ +- +- +-
++
+ pam_timestamp - authenticate using cached successful authentication attempts +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_tty_audit.xml b/doc/sag/pam_tty_audit.xml +index 86d1cd039..44de8105c 100644 +--- a/doc/sag/pam_tty_audit.xml ++++ b/doc/sag/pam_tty_audit.xml +@@ -1,38 +1,27 @@ +- +- +-
++
+ pam_tty_audit - enable/disable tty auditing +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_umask.xml b/doc/sag/pam_umask.xml +index b05350869..2fb200bbd 100644 +--- a/doc/sag/pam_umask.xml ++++ b/doc/sag/pam_umask.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_umask - set the file mode creation mask +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_unix.xml b/doc/sag/pam_unix.xml +index 24bbaec32..bb3412240 100644 +--- a/doc/sag/pam_unix.xml ++++ b/doc/sag/pam_unix.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_unix - traditional password authentication +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_userdb.xml b/doc/sag/pam_userdb.xml +index 47c2c7271..3c1bbc171 100644 +--- a/doc/sag/pam_userdb.xml ++++ b/doc/sag/pam_userdb.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_userdb - authenticate against a db database +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_warn.xml b/doc/sag/pam_warn.xml +index e2e7adba5..0f1376be6 100644 +--- a/doc/sag/pam_warn.xml ++++ b/doc/sag/pam_warn.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_warn - logs all PAM items +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_wheel.xml b/doc/sag/pam_wheel.xml +index 5ea011e36..76f020427 100644 +--- a/doc/sag/pam_wheel.xml ++++ b/doc/sag/pam_wheel.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_wheel - only permit root access to members of group wheel +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/doc/sag/pam_xauth.xml b/doc/sag/pam_xauth.xml +index 9aca9ffab..4c9ba35e7 100644 +--- a/doc/sag/pam_xauth.xml ++++ b/doc/sag/pam_xauth.xml +@@ -1,34 +1,24 @@ +- +- +-
++
+ pam_xauth - forward xauth keys between users +- +- ++ ++ + +-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
+- ++
++ +
+-
++
+\ No newline at end of file +diff --git a/modules/pam_access/README.xml b/modules/pam_access/README.xml +index 8c7d078b2..408aed009 100644 +--- a/modules/pam_access/README.xml ++++ b/modules/pam_access/README.xml +@@ -1,39 +1,23 @@ +- +- +---> +- +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_access.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_access-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_access.8.xml" xpointer='xpointer(id("pam_access-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_access/access.conf.5.xml b/modules/pam_access/access.conf.5.xml +index 8fdbc31de..ff1cb2237 100644 +--- a/modules/pam_access/access.conf.5.xml ++++ b/modules/pam_access/access.conf.5.xml +@@ -1,8 +1,4 @@ +- +- +- +- ++ + + + access.conf +@@ -16,7 +12,7 @@ + + + +- ++ + DESCRIPTION + + The /etc/security/access.conf file specifies +@@ -126,7 +122,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -135,7 +131,7 @@ + + + User root should be allowed to get access via +- cron, X11 terminal :0, ++ cron, X11 terminal :0, + tty1, ..., tty5, + tty6. + +@@ -216,7 +212,7 @@ + + + +- ++ + NOTES + + The default separators of list items in a field are space, ',', and tabulator +@@ -228,7 +224,7 @@ + + + +- ++ + SEE ALSO + + pam_access8, +@@ -237,7 +233,7 @@ + + + +- ++ + AUTHORS + + Original login.access5 +@@ -250,4 +246,4 @@ + introduced by Mike Becher <mike.becher@lrz-muenchen.de>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml +index db853410a..010e749e8 100644 +--- a/modules/pam_access/pam_access.8.xml ++++ b/modules/pam_access/pam_access.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_access + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_access + + PAM module for logdaemon style login access control +@@ -20,31 +17,31 @@ + + + +- ++ + pam_access.so +- ++ + debug + +- ++ + nodefgroup + +- ++ + noaudit + +- ++ + accessfile=file + +- ++ + fieldsep=sep + +- ++ + listsep=sep + + + + + +- ++ + DESCRIPTION + + The pam_access PAM module is mainly for access management. +@@ -92,13 +89,13 @@ + + + +- ++ + OPTIONS + + + + +- ++ accessfile=/path/to/access.conf + + + +@@ -111,7 +108,7 @@ + + + +- ++ debug + + + +@@ -123,7 +120,7 @@ + + + +- ++ noaudit + + + +@@ -134,19 +131,19 @@ + + + +- ++ fieldsep=separators + + + + This option modifies the field separator character that + pam_access will recognize when parsing the access + configuration file. For example: +- fieldsep=| will cause the ++ fieldsep=| will cause the + default `:' character to be treated as part of a field value + and `|' becomes the field separator. Doing this may be + useful in conjunction with a system that wants to use + pam_access with X based applications, since the +- PAM_TTY item is likely to be ++ PAM_TTY item is likely to be + of the form "hostname:0" which includes a `:' character in + its value. But you should not need this. + +@@ -155,14 +152,14 @@ + + + +- ++ listsep=separators + + + + This option modifies the list separator character that + pam_access will recognize when parsing the access + configuration file. For example: +- listsep=, will cause the ++ listsep=, will cause the + default ` ' (space) and `\t' (tab) characters to be treated + as part of a list element value and `,' becomes the only + list element separator. Doing this may be useful on a system +@@ -175,7 +172,7 @@ + + + +- ++ nodefgroup + + + +@@ -190,7 +187,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -198,7 +195,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -244,17 +241,17 @@ + + + +- ++ + FILES + + +- /etc/security/access.conf ++ /etc/security/access.conf + + Default configuration file + + + +- %vendordir%/security/access.conf ++ %vendordir%/security/access.conf + + Default configuration file if + /etc/security/access.conf does not exist. +@@ -263,7 +260,7 @@ + + + +- ++ + SEE ALSO + + +@@ -278,7 +275,7 @@ + + + +- ++ + AUTHORS + + The logdaemon style login access control scheme was designed and implemented by +@@ -289,4 +286,4 @@ + was developed and provided by Mike Becher <mike.becher@lrz-muenchen.de>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_debug/README.xml b/modules/pam_debug/README.xml +index ef41911be..cdcec7f43 100644 +--- a/modules/pam_debug/README.xml ++++ b/modules/pam_debug/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_debug.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_debug-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_debug.8.xml" xpointer='xpointer(id("pam_debug-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_debug/pam_debug.8.xml b/modules/pam_debug/pam_debug.8.xml +index 3d85f4d85..1c98f17e3 100644 +--- a/modules/pam_debug/pam_debug.8.xml ++++ b/modules/pam_debug/pam_debug.8.xml +@@ -1,51 +1,48 @@ +- +- +- +- ++ + + + pam_debug + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_debug + PAM module to debug the PAM stack + + + +- ++ + pam_debug.so +- ++ + auth=value + +- ++ + cred=value + +- ++ + acct=value + +- ++ + prechauthtok=value + +- ++ + chauthtok=value + +- ++ + auth=value + +- ++ + open_session=value + +- ++ + close_session=value + + + + +- ++ + DESCRIPTION + + The pam_debug PAM module is intended as a debugging aide for +@@ -54,12 +51,12 @@ + + + +- ++ + OPTIONS + + + +- ++ auth=value + + + +@@ -73,7 +70,7 @@ + + + +- ++ cred=value + + + +@@ -87,7 +84,7 @@ + + + +- ++ acct=value + + + +@@ -101,7 +98,7 @@ + + + +- ++ prechauthtok=value + + + +@@ -116,7 +113,7 @@ + + + +- ++ chauthtok=value + + + +@@ -126,13 +123,13 @@ + function will return + value if the + PAM_PRELIM_CHECK flag is +- not set. ++ not set. + + + + + +- ++ open_session=value + + + +@@ -146,7 +143,7 @@ + + + +- ++ close_session=value + + + +@@ -171,7 +168,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -179,7 +176,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -194,7 +191,7 @@ + + + +- ++ + EXAMPLES + + auth requisite pam_permit.so +@@ -206,7 +203,7 @@ auth sufficient pam_debug.so auth=success cred=success + + + +- ++ + SEE ALSO + + +@@ -221,11 +218,11 @@ auth sufficient pam_debug.so auth=success cred=success + + + +- ++ + AUTHOR + + pam_debug was written by Andrew G. Morgan <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_deny/README.xml b/modules/pam_deny/README.xml +index ff2e82b03..d3ba53ce0 100644 +--- a/modules/pam_deny/README.xml ++++ b/modules/pam_deny/README.xml +@@ -1,36 +1,23 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_deny.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_deny-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_deny.8.xml" xpointer='xpointer(id("pam_deny-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_deny/pam_deny.8.xml b/modules/pam_deny/pam_deny.8.xml +index a92835829..db8fcb635 100644 +--- a/modules/pam_deny/pam_deny.8.xml ++++ b/modules/pam_deny/pam_deny.8.xml +@@ -1,27 +1,24 @@ +- +- +- +- ++ + + + pam_deny + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_deny + The locking-out PAM module + + + +- ++ + pam_deny.so + + + +- ++ + + DESCRIPTION + +@@ -33,12 +30,12 @@ + + + +- ++ + OPTIONS + This module does not recognise any options. + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -46,7 +43,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -91,7 +88,7 @@ + + + +- ++ + EXAMPLES + + #%PAM-1.0 +@@ -110,7 +107,7 @@ other session required pam_deny.so + + + +- ++ + SEE ALSO + + +@@ -125,11 +122,11 @@ other session required pam_deny.so + + + +- ++ + AUTHOR + + pam_deny was written by Andrew G. Morgan <morgan@kernel.org> + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_echo/README.xml b/modules/pam_echo/README.xml +index b1556e38c..ceecf9ef6 100644 +--- a/modules/pam_echo/README.xml ++++ b/modules/pam_echo/README.xml +@@ -1,36 +1,23 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_echo.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_echo-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_echo.8.xml" xpointer='xpointer(id("pam_echo-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_echo/pam_echo.8.xml b/modules/pam_echo/pam_echo.8.xml +index ef76b022d..07b793d92 100644 +--- a/modules/pam_echo/pam_echo.8.xml ++++ b/modules/pam_echo/pam_echo.8.xml +@@ -1,15 +1,12 @@ +- +- +- +- ++ + + pam_echo + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_echo + PAM module for printing text messages + +@@ -17,15 +14,15 @@ + + + +- ++ + pam_echo.so +- ++ + file=/path/message + + + + +- ++ + DESCRIPTION + + The pam_echo PAM module is for printing +@@ -35,37 +32,37 @@ + + + +- %H ++ %H + + The name of the remote host (PAM_RHOST). + + + +- %h ++ %h + + The name of the local host. + + + +- %s ++ %s + + The service name (PAM_SERVICE). + + + +- %t ++ %t + + The name of the controlling terminal (PAM_TTY). + + + +- %U ++ %U + + The remote user name (PAM_RUSER). + + + +- %u ++ %u + + The local user name (PAM_USER). + +@@ -79,12 +76,12 @@ + + + +- ++ + OPTIONS + + + +- ++ file=/path/message + + + +@@ -96,7 +93,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -106,7 +103,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -137,7 +134,7 @@ + + + +- ++ + EXAMPLES + + For an example of the use of this module, we show how it may be +@@ -150,7 +147,7 @@ password required pam_unix.so + + + +- SEE ALSO ++ SEE ALSO + + + pam.conf8 +@@ -163,8 +160,8 @@ password required pam_unix.so + + + +- ++ + AUTHOR + Thorsten Kukuk <kukuk@thkukuk.de> + +- ++ +\ No newline at end of file +diff --git a/modules/pam_env/README.xml b/modules/pam_env/README.xml +index 21a9b8555..8becf8700 100644 +--- a/modules/pam_env/README.xml ++++ b/modules/pam_env/README.xml +@@ -1,39 +1,21 @@ +- +- +---> +- +-]> +- +-
+- +- ++
+ ++ + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_env.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_env-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_env.8.xml" xpointer='xpointer(id("pam_env-name")/*)'/> + +- +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_env/pam_env.8.xml b/modules/pam_env/pam_env.8.xml +index 75ff862be..bcb16036f 100644 +--- a/modules/pam_env/pam_env.8.xml ++++ b/modules/pam_env/pam_env.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_env + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_env + + PAM module to set/unset environment variables +@@ -20,31 +17,31 @@ + + + +- ++ + pam_env.so +- ++ + debug + +- ++ + conffile=conf-file + +- ++ + envfile=env-file + +- ++ + readenv=0|1 + +- ++ + user_envfile=env-file + +- ++ + user_readenv=0|1 + + + + + +- ++ + DESCRIPTION + + The pam_env PAM module allows the (un)setting of environment +@@ -77,13 +74,13 @@ + + + +- ++ + OPTIONS + + + + +- ++ conffile=/path/to/pam_env.conf + + + +@@ -96,7 +93,7 @@ + + + +- ++ debug + + + +@@ -108,7 +105,7 @@ + + + +- ++ envfile=/path/to/environment + + + +@@ -124,7 +121,7 @@ + + + +- ++ readenv=0|1 + + + +@@ -137,7 +134,7 @@ + + + +- ++ user_envfile=filename + + + +@@ -153,7 +150,7 @@ + + + +- ++ user_readenv=0|1 + + + +@@ -174,7 +171,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and module +@@ -182,7 +179,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -220,23 +217,23 @@ + + + +- ++ + FILES + + +- /etc/security/pam_env.conf ++ /etc/security/pam_env.conf + + Default configuration file + + + +- /etc/environment ++ /etc/environment + + Default environment file + + + +- $HOME/.pam_environment ++ $HOME/.pam_environment + + User specific environment file + +@@ -244,7 +241,7 @@ + + + +- ++ + SEE ALSO + + +@@ -262,10 +259,10 @@ + + + +- ++ + AUTHOR + + pam_env was written by Dave Kinchlea <kinch@kinch.ark.com>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_env/pam_env.conf.5.xml b/modules/pam_env/pam_env.conf.5.xml +index fca046fe3..f88791676 100644 +--- a/modules/pam_env/pam_env.conf.5.xml ++++ b/modules/pam_env/pam_env.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + pam_env.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -17,7 +14,7 @@ + + + +- ++ + DESCRIPTION + + +@@ -71,7 +68,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -117,7 +114,7 @@ + + + +- ++ + SEE ALSO + + pam_env8, +@@ -127,10 +124,10 @@ + + + +- ++ + AUTHOR + + pam_env was written by Dave Kinchlea <kinch@kinch.ark.com>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_exec/README.xml b/modules/pam_exec/README.xml +index 5e76cab30..1928d7f94 100644 +--- a/modules/pam_exec/README.xml ++++ b/modules/pam_exec/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_exec.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_exec-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_exec.8.xml" xpointer='xpointer(id("pam_exec-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_exec/pam_exec.8.xml b/modules/pam_exec/pam_exec.8.xml +index 7e89943ce..13abe6e64 100644 +--- a/modules/pam_exec/pam_exec.8.xml ++++ b/modules/pam_exec/pam_exec.8.xml +@@ -1,57 +1,54 @@ +- +- +- +- ++ + + + pam_exec + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_exec + PAM module which calls an external command + + + +- ++ + pam_exec.so +- ++ + debug + +- ++ + expose_authtok + +- ++ + seteuid + +- ++ + quiet + +- ++ + quiet_log + +- ++ + stdout + +- ++ + log=file + +- ++ + type=type + +- ++ + command + +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -83,7 +80,7 @@ + + + +- ++ + + OPTIONS + +@@ -91,7 +88,7 @@ + + + +- ++ debug + + + +@@ -102,7 +99,7 @@ + + + +- ++ expose_authtok + + + +@@ -117,7 +114,7 @@ + + + +- ++ log=file + + + +@@ -129,7 +126,7 @@ + + + +- ++ type=type + + + +@@ -140,7 +137,7 @@ + + + +- ++ stdout + + + +@@ -151,7 +148,7 @@ + + + +- ++ quiet + + + +@@ -164,7 +161,7 @@ + + + +- ++ quiet_log + + + +@@ -177,7 +174,7 @@ + + + +- ++ seteuid + + + +@@ -194,7 +191,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -202,7 +199,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -278,7 +275,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/passwd to +@@ -293,7 +290,7 @@ + + + +- ++ + SEE ALSO + + +@@ -308,7 +305,7 @@ + + + +- ++ + AUTHOR + + pam_exec was written by Thorsten Kukuk <kukuk@thkukuk.de> and +@@ -316,4 +313,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_faildelay/README.xml b/modules/pam_faildelay/README.xml +index 64d4acccb..8530a3d09 100644 +--- a/modules/pam_faildelay/README.xml ++++ b/modules/pam_faildelay/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_faildelay.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faildelay-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_faildelay.8.xml" xpointer='xpointer(id("pam_faildelay-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_faildelay/pam_faildelay.8.xml b/modules/pam_faildelay/pam_faildelay.8.xml +index 571072036..c31b5076d 100644 +--- a/modules/pam_faildelay/pam_faildelay.8.xml ++++ b/modules/pam_faildelay/pam_faildelay.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_faildelay + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_faildelay + Change the delay on failure per-application + + + +- ++ + pam_faildelay.so +- ++ + debug + +- ++ + delay=microseconds + + + + +- ++ + + DESCRIPTION + +@@ -41,13 +38,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ debug + + + +@@ -57,7 +54,7 @@ + + + +- ++ delay=N + + + +@@ -68,14 +65,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -97,7 +94,7 @@ + + + +- ++ + EXAMPLES + + The following example will set the delay on failure to +@@ -108,7 +105,7 @@ auth optional pam_faildelay.so delay=10000000 + + + +- ++ + SEE ALSO + + +@@ -126,11 +123,11 @@ auth optional pam_faildelay.so delay=10000000 + + + +- ++ + AUTHOR + + pam_faildelay was written by Darren Tucker <dtucker@zip.com.au>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_faillock/README.xml b/modules/pam_faillock/README.xml +index f0654dbe2..a62c917a9 100644 +--- a/modules/pam_faillock/README.xml ++++ b/modules/pam_faillock/README.xml +@@ -1,46 +1,31 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_faillock.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_faillock-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_faillock.8.xml" xpointer='xpointer(id("pam_faillock-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_faillock/faillock.8.xml b/modules/pam_faillock/faillock.8.xml +index 81d2107ca..74440fc81 100644 +--- a/modules/pam_faillock/faillock.8.xml ++++ b/modules/pam_faillock/faillock.8.xml +@@ -1,36 +1,33 @@ +- +- +- +- ++ + + + faillock + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + faillock + Tool for displaying and modifying the authentication failure record files + + + +- ++ + faillock +- ++ + --dir /path/to/tally-directory + +- ++ + --user username + +- ++ + --reset + + + + +- ++ + + DESCRIPTION + +@@ -51,13 +48,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ --conf /path/to/config-file + + + +@@ -68,7 +65,7 @@ + + + +- ++ --dir /path/to/tally-directory + + + +@@ -85,7 +82,7 @@ + + + +- ++ --user username + + + +@@ -95,7 +92,7 @@ + + + +- ++ --reset + + + +@@ -106,11 +103,11 @@ + + + +- ++ + FILES + + +- /var/run/faillock/* ++ /var/run/faillock/* + + the files logging the authentication failures for users + +@@ -118,7 +115,7 @@ + + + +- ++ + SEE ALSO + + +@@ -130,11 +127,11 @@ + + + +- ++ + AUTHOR + + faillock was written by Tomas Mraz. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_faillock/faillock.conf.5.xml b/modules/pam_faillock/faillock.conf.5.xml +index 8faa5915c..cc750fbff 100644 +--- a/modules/pam_faillock/faillock.conf.5.xml ++++ b/modules/pam_faillock/faillock.conf.5.xml +@@ -1,25 +1,22 @@ +- +- +- +- ++ + + + faillock.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + faillock.conf + pam_faillock configuration file + + +- ++ + + DESCRIPTION + +- faillock.conf provides a way to configure the ++ faillock.conf provides a way to configure the + default settings for locking the user after multiple failed authentication attempts. + This file is read by the pam_faillock module and is the + preferred method over configuring pam_faillock directly. +@@ -31,13 +28,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ dir=/path/to/tally-directory + + + +@@ -52,7 +49,7 @@ + + + +- ++ audit + + + +@@ -62,7 +59,7 @@ + + + +- ++ silent + + + +@@ -74,7 +71,7 @@ + + + +- ++ no_log_info + + + +@@ -84,7 +81,7 @@ + + + +- ++ local_users_only + + + +@@ -100,7 +97,7 @@ + + + +- ++ nodelay + + + +@@ -110,7 +107,7 @@ + + + +- ++ deny=n + + + +@@ -122,7 +119,7 @@ + + + +- ++ fail_interval=n + + + +@@ -135,7 +132,7 @@ + + + +- ++ unlock_time=n + + + +@@ -163,7 +160,7 @@ + + + +- ++ even_deny_root + + + +@@ -173,7 +170,7 @@ + + + +- ++ root_unlock_time=n + + + +@@ -187,7 +184,7 @@ + + + +- ++ admin_group=name + + + +@@ -202,7 +199,7 @@ + + + +- ++ + EXAMPLES + + /etc/security/faillock.conf file example: +@@ -214,11 +211,11 @@ silent + + + +- ++ + FILES + + +- /etc/security/faillock.conf ++ /etc/security/faillock.conf + + the config file for custom options + +@@ -226,7 +223,7 @@ silent + + + +- ++ + SEE ALSO + + +@@ -247,11 +244,11 @@ silent + + + +- ++ + AUTHOR + + pam_faillock was written by Tomas Mraz. The support for faillock.conf was written by Brian Ward. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_faillock/pam_faillock.8.xml b/modules/pam_faillock/pam_faillock.8.xml +index b7b7b0db9..ce0ae050b 100644 +--- a/modules/pam_faillock/pam_faillock.8.xml ++++ b/modules/pam_faillock/pam_faillock.8.xml +@@ -1,8 +1,4 @@ +- +- +- +- ++ + + + pam_faillock +@@ -10,63 +6,63 @@ + Linux-PAM Manual + + +- ++ + pam_faillock + Module counting authentication failures during a specified interval + + + +- ++ + auth ... pam_faillock.so +- ++ + preauth|authfail|authsucc + +- ++ + conf=/path/to/config-file + +- ++ + dir=/path/to/tally-directory + +- ++ + even_deny_root + +- ++ + deny=n + +- ++ + fail_interval=n + +- ++ + unlock_time=n + +- ++ + root_unlock_time=n + +- ++ + admin_group=name + +- ++ + audit + +- ++ + silent + +- ++ + no_log_info + + +- ++ + account ... pam_faillock.so +- ++ + dir=/path/to/tally-directory + +- ++ + no_log_info + + + + +- ++ + + DESCRIPTION + +@@ -78,20 +74,20 @@ + + + Normally, failed attempts to authenticate root will +- not cause the root account to become ++ not cause the root account to become + blocked, to prevent denial-of-service: if your users aren't given + shell accounts and root may only login via su or + at the machine console (not telnet/rsh, etc), this is safe. + + + +- ++ + + OPTIONS + + + +- ++ {preauth|authfail|authsucc} + + + +@@ -131,7 +127,7 @@ + + + +- ++ conf=/path/to/config-file + + + +@@ -156,7 +152,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and module types are +@@ -164,7 +160,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -222,7 +218,7 @@ + + + +- ++ + NOTES + + Configuring options on the module command line is not recommend. The +@@ -234,7 +230,7 @@ + + + Individual files with the failure records are created as owned by +- the user. This allows pam_faillock.so module ++ the user. This allows pam_faillock.so module + to work correctly when it is called from a screensaver. + + +@@ -249,7 +245,7 @@ + + + +- ++ + EXAMPLES + + Here are two possible configuration examples for /etc/pam.d/login. +@@ -320,11 +316,11 @@ session required pam_selinux.so open + + + +- ++ + FILES + + +- /var/run/faillock/* ++ /var/run/faillock/* + + the files logging the authentication failures for users + +@@ -336,13 +332,13 @@ session required pam_selinux.so open + + + +- /etc/security/faillock.conf ++ /etc/security/faillock.conf + + the config file for pam_faillock options + + + +- %vendordir%/security/faillock.conf ++ %vendordir%/security/faillock.conf + + + the config file for pam_faillock options. It will be used if +@@ -353,7 +349,7 @@ session required pam_selinux.so open + + + +- ++ + SEE ALSO + + +@@ -374,11 +370,11 @@ session required pam_selinux.so open + + + +- ++ + AUTHOR + + pam_faillock was written by Tomas Mraz. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_filter/README.xml b/modules/pam_filter/README.xml +index b76cb743f..ab0531748 100644 +--- a/modules/pam_filter/README.xml ++++ b/modules/pam_filter/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_filter.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_filter-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_filter.8.xml" xpointer='xpointer(id("pam_filter-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_filter/pam_filter.8.xml b/modules/pam_filter/pam_filter.8.xml +index 7309c352a..8015f41e5 100644 +--- a/modules/pam_filter/pam_filter.8.xml ++++ b/modules/pam_filter/pam_filter.8.xml +@@ -1,45 +1,42 @@ +- +- +- +- ++ + + + pam_filter + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_filter + PAM filter module + + + +- ++ + pam_filter.so +- ++ + debug + +- ++ + new_term + +- ++ + non_term + +- ++ + run1|run2 + +- ++ + filter + +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -66,7 +63,7 @@ + + + +- ++ + + OPTIONS + +@@ -74,7 +71,7 @@ + + + +- ++ debug + + + +@@ -85,7 +82,7 @@ + + + +- ++ new_term + + + +@@ -101,7 +98,7 @@ + + + +- ++ non_term + + + +@@ -112,7 +109,7 @@ + + + +- ++ runX + + + +@@ -174,7 +171,7 @@ + + + +- ++ filter + + + +@@ -188,7 +185,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -196,7 +193,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -223,7 +220,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/login to +@@ -236,7 +233,7 @@ + + + +- ++ + SEE ALSO + + +@@ -251,11 +248,11 @@ + + + +- ++ + AUTHOR + + pam_filter was written by Andrew G. Morgan <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_ftp/README.xml b/modules/pam_ftp/README.xml +index 65de28e36..f4606beee 100644 +--- a/modules/pam_ftp/README.xml ++++ b/modules/pam_ftp/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_ftp.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_ftp-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_ftp.8.xml" xpointer='xpointer(id("pam_ftp-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_ftp/pam_ftp.8.xml b/modules/pam_ftp/pam_ftp.8.xml +index 6f11f570f..03f367817 100644 +--- a/modules/pam_ftp/pam_ftp.8.xml ++++ b/modules/pam_ftp/pam_ftp.8.xml +@@ -1,36 +1,33 @@ +- +- +- +- ++ + + + pam_ftp + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_ftp + PAM module for anonymous access module + + + +- ++ + pam_ftp.so +- ++ + debug + +- ++ + ignore + +- ++ + users=XXX,YYY, + + + + +- ++ + + DESCRIPTION + +@@ -54,7 +51,7 @@ + + + +- ++ + + OPTIONS + +@@ -62,7 +59,7 @@ + + + +- ++ debug + + + +@@ -73,7 +70,7 @@ + + + +- ++ ignore + + + +@@ -85,7 +82,7 @@ + + + +- ++ ftp=XXX,YYY,... + + + +@@ -105,14 +102,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -139,7 +136,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/ftpd to +@@ -158,7 +155,7 @@ auth required pam_listfile.so \ + + + +- ++ + SEE ALSO + + +@@ -173,11 +170,11 @@ auth required pam_listfile.so \ + + + +- ++ + AUTHOR + + pam_ftp was written by Andrew G. Morgan <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_group/README.xml b/modules/pam_group/README.xml +index 387d69871..8ccd55d05 100644 +--- a/modules/pam_group/README.xml ++++ b/modules/pam_group/README.xml +@@ -1,34 +1,19 @@ +- +- +---> +- +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_group.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_group-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_group.8.xml" xpointer='xpointer(id("pam_group-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_group/group.conf.5.xml b/modules/pam_group/group.conf.5.xml +index 2b7fb3454..a8875b30a 100644 +--- a/modules/pam_group/group.conf.5.xml ++++ b/modules/pam_group/group.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + group.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -15,7 +12,7 @@ + configuration file for the pam_group module + + +- ++ + DESCRIPTION + + +@@ -98,7 +95,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -129,7 +126,7 @@ xsh; tty* ;%admin;Al0000-2400;plugdev + + + +- ++ + SEE ALSO + + pam_group8, +@@ -138,10 +135,10 @@ xsh; tty* ;%admin;Al0000-2400;plugdev + + + +- ++ + AUTHOR + + pam_group was written by Andrew G. Morgan <morgan@kernel.org>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_group/pam_group.8.xml b/modules/pam_group/pam_group.8.xml +index e4a59dfd9..695a7baf6 100644 +--- a/modules/pam_group/pam_group.8.xml ++++ b/modules/pam_group/pam_group.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_group + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_group + + PAM module for group access +@@ -20,13 +17,13 @@ + + + +- ++ + pam_group.so + + + + +- ++ + DESCRIPTION + + The pam_group PAM module does not authenticate the user, but instead +@@ -64,19 +61,19 @@ + + + +- ++ + OPTIONS + This module does not recognise any options. + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -130,11 +127,11 @@ + + + +- ++ + FILES + + +- /etc/security/group.conf ++ /etc/security/group.conf + + Default configuration file + +@@ -142,7 +139,7 @@ + + + +- ++ + SEE ALSO + + +@@ -157,10 +154,10 @@ + + + +- ++ + AUTHORS + + pam_group was written by Andrew G. Morgan <morgan@kernel.org>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_issue/README.xml b/modules/pam_issue/README.xml +index b5b61c3aa..36742c779 100644 +--- a/modules/pam_issue/README.xml ++++ b/modules/pam_issue/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_issue.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_issue-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_issue.8.xml" xpointer='xpointer(id("pam_issue-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_issue/pam_issue.8.xml b/modules/pam_issue/pam_issue.8.xml +index fb9b73777..20d324516 100644 +--- a/modules/pam_issue/pam_issue.8.xml ++++ b/modules/pam_issue/pam_issue.8.xml +@@ -1,110 +1,107 @@ +- +- +- +- ++ + + + pam_issue + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_issue + PAM module to add issue file to user prompt + + + +- ++ + pam_issue.so +- ++ + noesc + +- ++ + issue=issue-file-name + + + + +- ++ + + DESCRIPTION + + + pam_issue is a PAM module to prepend an issue file to the username + prompt. It also by default parses escape codes in the issue file +- similar to some common getty's (using \x format). ++ similar to some common getty's (using \x format). + + + Recognized escapes: + + + +- \d ++ \d + + current day + + + +- \l ++ \l + + name of this tty + + + +- \m ++ \m + + machine architecture (uname -m) + + + +- \n ++ \n + + machine's network node hostname (uname -n) + + + +- \o ++ \o + + domain name of this system + + + +- \r ++ \r + + release number of operating system (uname -r) + + + +- \t ++ \t + + current time + + + +- \s ++ \s + + operating system name (uname -s) + + + +- \u ++ \u + + number of users currently logged in + + + +- \U ++ \U + + +- same as \u except it is suffixed with "user" or ++ same as \u except it is suffixed with "user" or + "users" (eg. "1 user" or "10 users") + + + + +- \v ++ \v + + operating system version and build date (uname -v) + +@@ -113,7 +110,7 @@ + + + +- ++ + + OPTIONS + +@@ -121,7 +118,7 @@ + + + +- ++ noesc + + + +@@ -132,7 +129,7 @@ + + + +- ++ issue=issue-file-name + + + +@@ -146,14 +143,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -198,7 +195,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/login to +@@ -209,7 +206,7 @@ + + + +- ++ + SEE ALSO + + +@@ -224,11 +221,11 @@ + + + +- ++ + AUTHOR + + pam_issue was written by Ben Collins <bcollins@debian.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_keyinit/README.xml b/modules/pam_keyinit/README.xml +index 47659e89d..33059c7e1 100644 +--- a/modules/pam_keyinit/README.xml ++++ b/modules/pam_keyinit/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_keyinit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_keyinit-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_keyinit.8.xml" xpointer='xpointer(id("pam_keyinit-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_keyinit/pam_keyinit.8.xml b/modules/pam_keyinit/pam_keyinit.8.xml +index ff1e7d001..7b0a73be4 100644 +--- a/modules/pam_keyinit/pam_keyinit.8.xml ++++ b/modules/pam_keyinit/pam_keyinit.8.xml +@@ -1,36 +1,33 @@ +- +- +- +- ++ + + + pam_keyinit + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_keyinit + Kernel session keyring initialiser module + + + +- ++ + pam_keyinit.so +- ++ + debug + +- ++ + force + +- ++ + revoke + + + + +- ++ + DESCRIPTION + + The pam_keyinit PAM module ensures that the invoking process has a +@@ -71,7 +68,7 @@ + + + This module should not, generally, be invoked by programs like +- su, since it is usually desirable for the ++ su, since it is usually desirable for the + key set to percolate through to the alternate context. The keys have + their own permissions system to manage this. + +@@ -80,18 +77,18 @@ + can be obtained from: + + +- ++ + Keyutils +- ++ + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -104,7 +101,7 @@ + + + +- ++ force + + + +@@ -116,7 +113,7 @@ + + + +- ++ revoke + + + +@@ -130,14 +127,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -207,7 +204,7 @@ + + + +- ++ + EXAMPLES + + Add this line to your login entries to start each login session with its +@@ -222,7 +219,7 @@ session required pam_keyinit.so + + + +- ++ + SEE ALSO + + +@@ -240,11 +237,11 @@ session required pam_keyinit.so + + + +- ++ + AUTHOR + + pam_keyinit was written by David Howells, <dhowells@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_lastlog/README.xml b/modules/pam_lastlog/README.xml +index 7fe70339d..6b312435e 100644 +--- a/modules/pam_lastlog/README.xml ++++ b/modules/pam_lastlog/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_lastlog.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_lastlog-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_lastlog.8.xml" xpointer='xpointer(id("pam_lastlog-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_lastlog/pam_lastlog.8.xml b/modules/pam_lastlog/pam_lastlog.8.xml +index bada2ea02..1fd9d9dd4 100644 +--- a/modules/pam_lastlog/pam_lastlog.8.xml ++++ b/modules/pam_lastlog/pam_lastlog.8.xml +@@ -1,60 +1,57 @@ +- +- +- +- ++ + + + pam_lastlog + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_lastlog + PAM module to display date of last login and perform inactive account lock out + + + +- ++ + pam_lastlog.so +- ++ + debug + +- ++ + silent + +- ++ + never + +- ++ + nodate + +- ++ + nohost + +- ++ + noterm + +- ++ + nowtmp + +- ++ + noupdate + +- ++ + showfailed + +- ++ + inactive=<days> + +- ++ + unlimited + + + + +- ++ + + DESCRIPTION + +@@ -83,13 +80,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ debug + + + +@@ -99,7 +96,7 @@ + + + +- ++ silent + + + +@@ -111,7 +108,7 @@ + + + +- ++ never + + + +@@ -124,7 +121,7 @@ + + + +- ++ nodate + + + +@@ -134,7 +131,7 @@ + + + +- ++ noterm + + + +@@ -145,7 +142,7 @@ + + + +- ++ nohost + + + +@@ -156,7 +153,7 @@ + + + +- ++ nowtmp + + + +@@ -166,7 +163,7 @@ + + + +- ++ noupdate + + + +@@ -176,7 +173,7 @@ + + + +- ++ showfailed + + + +@@ -188,7 +185,7 @@ + + + +- ++ inactive=<days> + + + +@@ -201,7 +198,7 @@ + + + +- ++ unlimited + + + +@@ -214,7 +211,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and module type +@@ -225,7 +222,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -282,7 +279,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/login to +@@ -300,11 +297,11 @@ + + + +- ++ + FILES + + +- /var/log/lastlog ++ /var/log/lastlog + + Lastlog logging file + +@@ -312,7 +309,7 @@ + + + +- ++ + SEE ALSO + + +@@ -330,7 +327,7 @@ + + + +- ++ + AUTHOR + + pam_lastlog was written by Andrew G. Morgan <morgan@kernel.org>. +@@ -340,4 +337,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_limits/README.xml b/modules/pam_limits/README.xml +index 964a5a218..25a463cc4 100644 +--- a/modules/pam_limits/README.xml ++++ b/modules/pam_limits/README.xml +@@ -1,39 +1,23 @@ +- +- +---> +- +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_limits.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_limits-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_limits.8.xml" xpointer='xpointer(id("pam_limits-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_limits/limits.conf.5.xml b/modules/pam_limits/limits.conf.5.xml +index c5bd6768c..2177da1f3 100644 +--- a/modules/pam_limits/limits.conf.5.xml ++++ b/modules/pam_limits/limits.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + limits.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -15,7 +12,7 @@ + configuration file for the pam_limits module + + +- ++ + DESCRIPTION + + The pam_limits.so module applies ulimit limits, +@@ -38,7 +35,7 @@ + + + +- ++ <domain> + + + +@@ -49,38 +46,35 @@ + + + +- a groupname, with @group syntax. ++ a groupname, with @group syntax. + This should not be confused with netgroups. + + + + +- the wildcard *, for default entry. ++ the wildcard *, for default entry. + + + + +- the wildcard %, for maxlogins limit only, +- can also be used with %group syntax. If the +- % wildcard is used alone it is identical +- to using * with maxsyslogins limit. With +- a group specified after % it limits the total ++ the wildcard %, for maxlogins limit only, ++ can also be used with %group syntax. If the ++ % wildcard is used alone it is identical ++ to using * with maxsyslogins limit. With ++ a group specified after % it limits the total + number of logins of all users that are member of the group. + + + + +- an uid range specified as <min_uid>:<max_uid>. If min_uid ++ an uid range specified as <min_uid>:<max_uid>. If min_uid + is omitted, the match is exact for the max_uid. If max_uid is omitted, all + uids greater than or equal min_uid match. + + + + +- a gid range specified as @<min_gid>:<max_gid>. If min_gid ++ a gid range specified as @<min_gid>:<max_gid>. If min_gid + is omitted, the match is exact for the max_gid. If max_gid is omitted, all + gids greater than or equal min_gid match. For the exact match all groups including + the user's supplementary groups are examined. For the range matches only +@@ -89,8 +83,7 @@ + + + +- a gid specified as %:<gid> applicable ++ a gid specified as %:<gid> applicable + to maxlogins limit only. It limits the total number of logins of all users + that are member of the group with the specified gid. + +@@ -101,38 +94,38 @@ + + + +- ++ <type> + + + + +- ++ hard + + +- for enforcing hard resource limits. ++ for enforcing hard resource limits. + These limits are set by the superuser and enforced by the Kernel. + The user cannot raise his requirement of system resources above such values. + + + + +- ++ soft + + +- for enforcing soft resource limits. ++ for enforcing soft resource limits. + These limits are ones that the user can move up or down within the +- permitted range by any pre-existing hard ++ permitted range by any pre-existing hard + limits. The values specified with this token can be thought of as + default values, for normal system usage. + + + + +- ++ - + + +- for enforcing both soft and +- hard resource limits together. ++ for enforcing both soft and ++ hard resource limits together. + + + Note, if you specify a type of '-' but neglect to supply the +@@ -147,79 +140,79 @@ + + + +- ++ <item> + + + + +- ++ core + + limits the core file size (KB) + + + +- ++ data + + maximum data size (KB) + + + +- ++ fsize + + maximum filesize (KB) + + + +- ++ memlock + + maximum locked-in-memory address space (KB) + + + +- ++ nofile + + maximum number of open file descriptors + + + +- ++ rss + + maximum resident set size (KB) (Ignored in Linux 2.4.30 and higher) + + + +- ++ stack + + maximum stack size (KB) + + + +- ++ cpu + + maximum CPU time (minutes) + + + +- ++ nproc + + maximum number of processes + + + +- ++ as + + address space limit (KB) + + + +- ++ maxlogins + + maximum number of logins for this user (this limit does + not apply to user with uid=0) + + + +- ++ maxsyslogins + + maximum number of all logins on system; user is not + allowed to log-in if total number of all user logins is +@@ -228,46 +221,46 @@ + + + +- ++ nonewprivs + + value of 0 or 1; if set to 1 disables acquiring new + privileges by invoking prctl(PR_SET_NO_NEW_PRIVS) + + + +- ++ priority + + the priority to run user process with (negative + values boost process priority) + + + +- ++ locks + + maximum locked files (Linux 2.4 and higher) + + + +- ++ sigpending + + maximum number of pending signals (Linux 2.6 and higher) + + + +- ++ msgqueue + + maximum memory used by POSIX message queues (bytes) + (Linux 2.6 and higher) + + + +- ++ nice + + maximum nice priority allowed to raise to (Linux 2.6.12 and higher) values: [-20,19] + + + +- ++ rtprio + + maximum realtime priority allowed for non-privileged processes + (Linux 2.6.12 and higher) +@@ -281,9 +274,9 @@ + + All items support the values -1, + unlimited or infinity indicating no limit, +- except for priority, nice, +- and nonewprivs. +- If nofile is to be set to one of these values, ++ except for priority, nice, ++ and nonewprivs. ++ If nofile is to be set to one of these values, + it will be set to the contents of /proc/sys/fs/nr_open instead (see setrlimit(3)). + + +@@ -309,7 +302,7 @@ + + + In the limits configuration file, the +- '#' character introduces a comment ++ '#' character introduces a comment + - after which the rest of the line is ignored. + + +@@ -319,7 +312,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -340,7 +333,7 @@ ftp hard nproc 0 + + + +- ++ + SEE ALSO + + pam_limits8, +@@ -351,10 +344,10 @@ ftp hard nproc 0 + + + +- ++ + AUTHOR + + pam_limits was initially written by Cristian Gafton <gafton@redhat.com> + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml +index 422924fe8..cca046cce 100644 +--- a/modules/pam_limits/pam_limits.8.xml ++++ b/modules/pam_limits/pam_limits.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_limits + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_limits + + PAM module to limit resources +@@ -20,28 +17,28 @@ + + + +- ++ + pam_limits.so +- ++ + conf=/path/to/limits.conf + +- ++ + debug + +- ++ + set_all + +- ++ + utmp_early + +- ++ + noaudit + + + + + +- ++ + DESCRIPTION + + The pam_limits PAM module sets limits on the system resources that can be +@@ -84,12 +81,12 @@ + + + +- ++ + OPTIONS + + + +- ++ conf=/path/to/limits.conf + + + +@@ -100,7 +97,7 @@ + + + +- ++ debug + + + +@@ -110,7 +107,7 @@ + + + +- ++ set_all + + + +@@ -124,7 +121,7 @@ + + + +- ++ utmp_early + + + +@@ -139,7 +136,7 @@ + + + +- ++ noaudit + + + +@@ -150,14 +147,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -219,17 +216,17 @@ + + + +- ++ + FILES + + +- /etc/security/limits.conf ++ /etc/security/limits.conf + + Default configuration file + + + +- %vendordir%/security/limits.conf ++ %vendordir%/security/limits.conf + + Default configuration file if + /etc/security/limits.conf does not exist. +@@ -238,7 +235,7 @@ + + + +- ++ + EXAMPLES + + For the services you need resources limits (login for example) put a +@@ -257,7 +254,7 @@ session required pam_limits.so + + + +- ++ + SEE ALSO + + +@@ -272,10 +269,10 @@ session required pam_limits.so + + + +- ++ + AUTHORS + + pam_limits was initially written by Cristian Gafton <gafton@redhat.com> + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_listfile/README.xml b/modules/pam_listfile/README.xml +index d851aef30..d0b601075 100644 +--- a/modules/pam_listfile/README.xml ++++ b/modules/pam_listfile/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_listfile.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_listfile-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_listfile.8.xml" xpointer='xpointer(id("pam_listfile-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_listfile/pam_listfile.8.xml b/modules/pam_listfile/pam_listfile.8.xml +index 15f047c27..8847415a5 100644 +--- a/modules/pam_listfile/pam_listfile.8.xml ++++ b/modules/pam_listfile/pam_listfile.8.xml +@@ -1,45 +1,42 @@ +- +- +- +- ++ + + + pam_listfile + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_listfile + deny or allow services based on an arbitrary file + + + +- ++ + pam_listfile.so +- ++ + item=[tty|user|rhost|ruser|group|shell] + +- ++ + sense=[allow|deny] + +- ++ + file=/path/filename + +- ++ + onerr=[succeed|fail] + +- ++ + apply=[user|@group] + +- ++ + quiet + + + + +- ++ + + DESCRIPTION + +@@ -93,7 +90,7 @@ + + + +- ++ + + OPTIONS + +@@ -101,7 +98,7 @@ + + + +- ++ item=[tty|user|rhost|ruser|group|shell] + + + +@@ -112,7 +109,7 @@ + + + +- ++ sense=[allow|deny] + + + +@@ -124,7 +121,7 @@ + + + +- ++ file=/path/filename + + + +@@ -136,7 +133,7 @@ + + + +- ++ onerr=[succeed|fail] + + + +@@ -148,7 +145,7 @@ + + + +- ++ apply=[user|@group] + + + +@@ -161,7 +158,7 @@ + + + +- ++ quiet + + + +@@ -175,7 +172,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -183,7 +180,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -235,7 +232,7 @@ + + + +- ++ + EXAMPLES + + Classic 'ftpusers' authentication can be implemented with this entry +@@ -271,7 +268,7 @@ auth required pam_listfile.so \ + + + +- ++ + SEE ALSO + + +@@ -286,7 +283,7 @@ auth required pam_listfile.so \ + + + +- ++ + AUTHOR + + pam_listfile was written by Michael K. Johnson <johnsonm@redhat.com> +@@ -294,4 +291,4 @@ auth required pam_listfile.so \ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_localuser/README.xml b/modules/pam_localuser/README.xml +index 4ab56d9df..f1b05d1a5 100644 +--- a/modules/pam_localuser/README.xml ++++ b/modules/pam_localuser/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_localuser.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_localuser-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_localuser.8.xml" xpointer='xpointer(id("pam_localuser-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_localuser/pam_localuser.8.xml b/modules/pam_localuser/pam_localuser.8.xml +index b3c1886b3..2002d1d67 100644 +--- a/modules/pam_localuser/pam_localuser.8.xml ++++ b/modules/pam_localuser/pam_localuser.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_localuser + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_localuser + require users to be listed in /etc/passwd + + + +- ++ + pam_localuser.so +- ++ + debug + +- ++ + file=/path/passwd + + + + +- ++ + + DESCRIPTION + +@@ -47,7 +44,7 @@ + + + +- ++ + + OPTIONS + +@@ -55,7 +52,7 @@ + + + +- ++ debug + + + +@@ -66,7 +63,7 @@ + + + +- ++ file=/path/passwd + + + +@@ -80,7 +77,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -88,7 +85,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -153,7 +150,7 @@ + + + +- ++ + EXAMPLES + + Add the following lines to /etc/pam.d/su to +@@ -165,11 +162,11 @@ account required pam_wheel.so + + + +- ++ + FILES + + +- /etc/passwd ++ /etc/passwd + + Local user account information. + +@@ -177,7 +174,7 @@ account required pam_wheel.so + + + +- ++ + SEE ALSO + + +@@ -192,11 +189,11 @@ account required pam_wheel.so + + + +- ++ + AUTHOR + + pam_localuser was written by Nalin Dahyabhai <nalin@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_loginuid/README.xml b/modules/pam_loginuid/README.xml +index 3bcd38abd..f972105f9 100644 +--- a/modules/pam_loginuid/README.xml ++++ b/modules/pam_loginuid/README.xml +@@ -1,36 +1,23 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_loginuid.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_loginuid-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_loginuid.8.xml" xpointer='xpointer(id("pam_loginuid-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_loginuid/pam_loginuid.8.xml b/modules/pam_loginuid/pam_loginuid.8.xml +index 9513b0e49..d5285f029 100644 +--- a/modules/pam_loginuid/pam_loginuid.8.xml ++++ b/modules/pam_loginuid/pam_loginuid.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + pam_loginuid + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_loginuid + Record user's login uid to the process attribute + + + +- ++ + pam_loginuid.so +- ++ + require_auditd + + + + +- ++ + + DESCRIPTION + +@@ -40,12 +37,12 @@ + + + +- ++ + OPTIONS + + + +- ++ require_auditd + + + +@@ -57,14 +54,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -98,7 +95,7 @@ + + + +- ++ + EXAMPLES + + #%PAM-1.0 +@@ -111,7 +108,7 @@ session required pam_loginuid.so + + + +- ++ + SEE ALSO + + +@@ -132,11 +129,11 @@ session required pam_loginuid.so + + + +- ++ + AUTHOR + + pam_loginuid was written by Steve Grubb <sgrubb@redhat.com> + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_mail/README.xml b/modules/pam_mail/README.xml +index 4165d857c..5dc89a855 100644 +--- a/modules/pam_mail/README.xml ++++ b/modules/pam_mail/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_mail.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mail-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_mail.8.xml" xpointer='xpointer(id("pam_mail-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_mail/pam_mail.8.xml b/modules/pam_mail/pam_mail.8.xml +index 95216b6cf..2c0c0543a 100644 +--- a/modules/pam_mail/pam_mail.8.xml ++++ b/modules/pam_mail/pam_mail.8.xml +@@ -1,54 +1,51 @@ +- +- +- +- ++ + + + pam_mail + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_mail + Inform about available mail + + + +- ++ + pam_mail.so +- ++ + close + +- ++ + debug + +- ++ + dir=maildir + +- ++ + empty + +- ++ + hash=count + +- ++ + noenv + +- ++ + nopen + +- ++ + quiet + +- ++ + standard + + + + +- ++ + + DESCRIPTION + +@@ -58,18 +55,18 @@ + that has credential or session hooks. It gives a single message + indicating the newness of any mail it finds + in the user's mail folder. This module also sets the PAM +- environment variable, MAIL, to the ++ environment variable, MAIL, to the + user's mail directory. + + + If the mail spool file (be it /var/mail/$USER + or a pathname given with the parameter) is + a directory then pam_mail assumes it is in the +- Maildir format. ++ Maildir format. + + + +- ++ + + OPTIONS + +@@ -77,7 +74,7 @@ + + + +- ++ close + + + +@@ -88,7 +85,7 @@ + + + +- ++ debug + + + +@@ -99,7 +96,7 @@ + + + +- ++ dir=maildir + + + +@@ -116,7 +113,7 @@ + + + +- ++ empty + + + +@@ -127,7 +124,7 @@ + + + +- ++ hash=count + + + +@@ -141,11 +138,11 @@ + + + +- ++ noenv + + + +- Do not set the MAIL ++ Do not set the MAIL + environment variable. + + +@@ -153,12 +150,12 @@ + + + +- ++ nopen + + + + Don't print any mail information on login. This flag is +- useful to get the MAIL ++ useful to get the MAIL + environment variable set, but to not display any information + about it. + +@@ -167,7 +164,7 @@ + + + +- ++ quiet + + + +@@ -178,7 +175,7 @@ + + + +- ++ standard + + + +@@ -193,7 +190,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and +@@ -202,7 +199,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -244,7 +241,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/login to +@@ -255,7 +252,7 @@ session optional pam_mail.so standard + + + +- ++ + SEE ALSO + + +@@ -270,11 +267,11 @@ session optional pam_mail.so standard + + + +- ++ + AUTHOR + + pam_mail was written by Andrew G. Morgan <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_mkhomedir/README.xml b/modules/pam_mkhomedir/README.xml +index 978cbe776..ef9989563 100644 +--- a/modules/pam_mkhomedir/README.xml ++++ b/modules/pam_mkhomedir/README.xml +@@ -1,36 +1,23 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_mkhomedir.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_mkhomedir-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_mkhomedir.8.xml" xpointer='xpointer(id("pam_mkhomedir-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_mkhomedir/mkhomedir_helper.8.xml b/modules/pam_mkhomedir/mkhomedir_helper.8.xml +index 8a76f2d6c..0f4c4b401 100644 +--- a/modules/pam_mkhomedir/mkhomedir_helper.8.xml ++++ b/modules/pam_mkhomedir/mkhomedir_helper.8.xml +@@ -1,31 +1,28 @@ +- +- +- +- ++ + + + mkhomedir_helper + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + mkhomedir_helper + Helper binary that creates home directories + + + +- ++ + mkhomedir_helper +- ++ + user + +- ++ + umask +- ++ + path-to-skel +- ++ + home_mode + + +@@ -33,7 +30,7 @@ + + + +- ++ + + DESCRIPTION + +@@ -63,7 +60,7 @@ + + + +- ++ + SEE ALSO + + +@@ -72,7 +69,7 @@ + + + +- ++ + AUTHOR + + Written by Tomas Mraz based on the code originally in +@@ -80,4 +77,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_mkhomedir/pam_mkhomedir.8.xml b/modules/pam_mkhomedir/pam_mkhomedir.8.xml +index 10109067c..ad957248c 100644 +--- a/modules/pam_mkhomedir/pam_mkhomedir.8.xml ++++ b/modules/pam_mkhomedir/pam_mkhomedir.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_mkhomedir + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_mkhomedir + + PAM module to create users home directory +@@ -20,25 +17,25 @@ + + + +- ++ + pam_mkhomedir.so +- ++ + silent + +- ++ + debug + +- ++ + umask=mode + +- ++ + skel=skeldir + + + + + +- ++ + DESCRIPTION + + The pam_mkhomedir PAM module will create a users home directory +@@ -55,13 +52,13 @@ + + + +- ++ + OPTIONS + + + + +- ++ silent + + + +@@ -72,7 +69,7 @@ + + + +- ++ debug + + + +@@ -86,7 +83,7 @@ + + + +- ++ umask=mask + + + +@@ -106,7 +103,7 @@ + + + +- ++ skel=/path/to/skel/directory + + + +@@ -119,14 +116,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -165,11 +162,11 @@ + + + +- ++ + FILES + + +- /etc/skel ++ /etc/skel + + Default skel directory + +@@ -177,7 +174,7 @@ + + + +- ++ + EXAMPLES + + A sample /etc/pam.d/login file: +@@ -198,7 +195,7 @@ + + + +- ++ + SEE ALSO + + +@@ -210,10 +207,10 @@ + + + +- ++ + AUTHOR + + pam_mkhomedir was written by Jason Gunthorpe <jgg@debian.org>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_motd/README.xml b/modules/pam_motd/README.xml +index 779e4d171..9e8edadff 100644 +--- a/modules/pam_motd/README.xml ++++ b/modules/pam_motd/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_motd.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_motd-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_motd.8.xml" xpointer='xpointer(id("pam_motd-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_motd/pam_motd.8.xml b/modules/pam_motd/pam_motd.8.xml +index 0afd4c99e..74420371f 100644 +--- a/modules/pam_motd/pam_motd.8.xml ++++ b/modules/pam_motd/pam_motd.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_motd + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_motd + Display the motd file + + + +- ++ + pam_motd.so +- ++ + motd=/path/filename + +- ++ + motd_dir=/path/dirname.d + + + + +- ++ + + DESCRIPTION + +@@ -38,7 +35,7 @@ + following locations: + + +- ++ + /etc/motd + /run/motd + /usr/lib/motd +@@ -79,19 +76,19 @@ + ln -s /dev/null /etc/motd.d/my_motd + + +- The MOTD_SHOWN=pam environment variable ++ The MOTD_SHOWN=pam environment variable + is set after showing the motd files, even when all of them were silenced + using symbolic links. + + + +- ++ + + OPTIONS + + + +- ++ motd=/path/filename + + + +@@ -104,7 +101,7 @@ + + + +- ++ motd_dir=/path/dirname.d + + + +@@ -123,14 +120,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -160,7 +157,7 @@ + + + +- ++ + EXAMPLES + + The suggested usage for /etc/pam.d/login is: +@@ -183,7 +180,7 @@ session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d + + + +- ++ + SEE ALSO + + +@@ -201,7 +198,7 @@ session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d + + + +- ++ + AUTHOR + + pam_motd was written by Ben Collins <bcollins@debian.org>. +@@ -212,4 +209,4 @@ session optional pam_motd.so motd=/elsewhere/motd motd_dir=/elsewhere/motd.d + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_namespace/README.xml b/modules/pam_namespace/README.xml +index 4ef99c9fd..f94cb0650 100644 +--- a/modules/pam_namespace/README.xml ++++ b/modules/pam_namespace/README.xml +@@ -1,44 +1,27 @@ +- +- +---> +- +-]> +- +-
+- +- ++
++ ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_namespace.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_namespace-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_namespace.8.xml" xpointer='xpointer(id("pam_namespace-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml +index 67f8c043e..d398639b2 100644 +--- a/modules/pam_namespace/namespace.conf.5.xml ++++ b/modules/pam_namespace/namespace.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + namespace.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -16,7 +13,7 @@ + + + +- ++ + DESCRIPTION + + +@@ -175,7 +172,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -220,7 +217,7 @@ + + + +- ++ + SEE ALSO + + pam_namespace8, +@@ -229,11 +226,11 @@ + + + +- ++ + AUTHORS + + The namespace.conf manual page was written by Janak Desai <janak@us.ibm.com>. + More features added by Tomas Mraz <tmraz@redhat.com>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml +index ddaa00b4f..598037a49 100644 +--- a/modules/pam_namespace/pam_namespace.8.xml ++++ b/modules/pam_namespace/pam_namespace.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_namespace + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_namespace + + PAM module for configuring namespace for a session +@@ -20,46 +17,46 @@ + + + +- ++ + pam_namespace.so +- ++ + debug + +- ++ + unmnt_remnt + +- ++ + unmnt_only + +- ++ + require_selinux + +- ++ + gen_hash + +- ++ + ignore_config_error + +- ++ + ignore_instance_parent_mode + +- ++ + unmount_on_close + +- ++ + use_current_context + +- ++ + use_default_context + +- ++ + mount_private + + + + + +- ++ + DESCRIPTION + + The pam_namespace PAM module sets up a private namespace for a session +@@ -94,13 +91,13 @@ + + + +- ++ + OPTIONS + + + + +- ++ debug + + + +@@ -111,7 +108,7 @@ + + + +- ++ unmnt_remnt + + + +@@ -131,7 +128,7 @@ + + + +- ++ unmnt_only + + + +@@ -146,7 +143,7 @@ + + + +- ++ require_selinux + + + +@@ -157,7 +154,7 @@ + + + +- ++ gen_hash + + + +@@ -170,7 +167,7 @@ + + + +- ++ ignore_config_error + + + +@@ -186,7 +183,7 @@ + + + +- ++ ignore_instance_parent_mode + + + +@@ -201,7 +198,7 @@ + + + +- ++ unmount_on_close + + + +@@ -218,7 +215,7 @@ + + + +- ++ use_current_context + + + +@@ -232,7 +229,7 @@ + + + +- ++ use_default_context + + + +@@ -246,7 +243,7 @@ + + + +- ++ mount_private + + + +@@ -271,7 +268,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. +@@ -279,7 +276,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -309,18 +306,18 @@ + + + +- ++ + FILES + + +- /etc/security/namespace.conf ++ /etc/security/namespace.conf + + Main configuration file + + + + +- %vendordir%/security/namespace.conf ++ %vendordir%/security/namespace.conf + + Default configuration file if + /etc/security/namespace.conf does not exist. +@@ -328,28 +325,28 @@ + + + +- /etc/security/namespace.d ++ /etc/security/namespace.d + + Directory for additional configuration files + + + + +- %vendordir%/security/namespace.d ++ %vendordir%/security/namespace.d + + Directory for additional vendor specific configuration files. + + + + +- /etc/security/namespace.init ++ /etc/security/namespace.init + + Init script for instance directories + + + + +- %vendordir%/security/namespace.init ++ %vendordir%/security/namespace.init + + Vendor init script for instance directories if + /etc/security/namespace.init does not exist. +@@ -359,7 +356,7 @@ + + + +- ++ + EXAMPLES + + +@@ -379,7 +376,7 @@ + + + +- ++ + SEE ALSO + + +@@ -397,7 +394,7 @@ + + + +- ++ + AUTHORS + + The namespace setup scheme was designed by Stephen Smalley, Janak Desai +@@ -408,4 +405,4 @@ + <tmraz@redhat.com>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_namespace/pam_namespace_helper.8.xml b/modules/pam_namespace/pam_namespace_helper.8.xml +index 2f5adbed7..002c254a1 100644 +--- a/modules/pam_namespace/pam_namespace_helper.8.xml ++++ b/modules/pam_namespace/pam_namespace_helper.8.xml +@@ -1,27 +1,24 @@ +- +- +- +- ++ + + + pam_namespace_helper + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_namespace_helper + Helper binary that creates home directories + + + +- ++ + pam_namespace_helper + + + +- ++ + + DESCRIPTION + +@@ -43,7 +40,7 @@ + + + +- ++ + SEE ALSO + + +@@ -52,11 +49,11 @@ + + + +- ++ + AUTHOR + + Written by Topi Miettinen. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_nologin/README.xml b/modules/pam_nologin/README.xml +index bc0808e73..5a9933244 100644 +--- a/modules/pam_nologin/README.xml ++++ b/modules/pam_nologin/README.xml +@@ -1,46 +1,31 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_nologin.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_nologin-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_nologin.8.xml" xpointer='xpointer(id("pam_nologin-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_nologin/pam_nologin.8.xml b/modules/pam_nologin/pam_nologin.8.xml +index c86e3763d..1ea725ce8 100644 +--- a/modules/pam_nologin/pam_nologin.8.xml ++++ b/modules/pam_nologin/pam_nologin.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_nologin + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_nologin + Prevent non-root users from login + + + +- ++ + pam_nologin.so +- ++ + file=/path/nologin + +- ++ + successok + + + + +- ++ + + DESCRIPTION + +@@ -40,13 +37,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ file=/path/nologin + + + +@@ -58,7 +55,7 @@ + + + +- ++ successok + + + +@@ -69,7 +66,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and module +@@ -77,7 +74,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -123,7 +120,7 @@ + + + +- ++ + EXAMPLES + + The suggested usage for /etc/pam.d/login is: +@@ -132,7 +129,7 @@ auth required pam_nologin.so + + + +- ++ + NOTES + + In order to make this module effective, all login methods should be +@@ -147,7 +144,7 @@ auth required pam_nologin.so + + + +- ++ + SEE ALSO + + +@@ -165,11 +162,11 @@ auth required pam_nologin.so + + + +- ++ + AUTHOR + + pam_nologin was written by Michael K. Johnson <johnsonm@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_permit/README.xml b/modules/pam_permit/README.xml +index acb38b512..c08425f81 100644 +--- a/modules/pam_permit/README.xml ++++ b/modules/pam_permit/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_permit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_permit-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_permit.8.xml" xpointer='xpointer(id("pam_permit-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_permit/pam_permit.8.xml b/modules/pam_permit/pam_permit.8.xml +index 6bb496583..0634e5eb6 100644 +--- a/modules/pam_permit/pam_permit.8.xml ++++ b/modules/pam_permit/pam_permit.8.xml +@@ -1,27 +1,24 @@ +- +- +- +- ++ + + + pam_permit + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_permit + The promiscuous module + + + +- ++ + pam_permit.so + + + +- ++ + + DESCRIPTION + +@@ -41,13 +38,13 @@ + + + +- ++ + + OPTIONS + This module does not recognise any options. + + +- ++ + MODULE TYPES PROVIDED + + The , , +@@ -56,7 +53,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -70,7 +67,7 @@ + + + +- ++ + EXAMPLES + + Add this line to your other login entries to disable account +@@ -81,7 +78,7 @@ account required pam_permit.so + + + +- ++ + SEE ALSO + + +@@ -96,11 +93,11 @@ account required pam_permit.so + + + +- ++ + AUTHOR + + pam_permit was written by Andrew G. Morgan, <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_pwhistory/README.xml b/modules/pam_pwhistory/README.xml +index f048e321c..194edbc73 100644 +--- a/modules/pam_pwhistory/README.xml ++++ b/modules/pam_pwhistory/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_pwhistory.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_pwhistory-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_pwhistory.8.xml" xpointer='xpointer(id("pam_pwhistory-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml +index 2a8fa7f6a..62848666b 100644 +--- a/modules/pam_pwhistory/pam_pwhistory.8.xml ++++ b/modules/pam_pwhistory/pam_pwhistory.8.xml +@@ -1,52 +1,49 @@ +- +- +- +- ++ + + + pam_pwhistory + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_pwhistory + PAM module to remember last passwords + + + +- ++ + pam_pwhistory.so +- ++ + debug + +- ++ + use_authtok + +- ++ + enforce_for_root + +- ++ + remember=N + +- ++ + retry=N + +- ++ + authtok_type=STRING + +- ++ + file=/path/filename + +- ++ + conf=/path/to/config-file + + + + + +- ++ + + DESCRIPTION + +@@ -64,12 +61,12 @@ + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -82,7 +79,7 @@ + + + +- ++ use_authtok + + + +@@ -95,7 +92,7 @@ + + + +- ++ enforce_for_root + + + +@@ -105,7 +102,7 @@ + + + +- ++ remember=N + + + +@@ -119,7 +116,7 @@ + + + +- ++ retry=N + + + +@@ -132,7 +129,7 @@ + + + +- ++ authtok_type=STRING + + + +@@ -145,7 +142,7 @@ + + + +- ++ file=/path/filename + + + +@@ -158,7 +155,7 @@ + + + +- ++ conf=/path/to/config-file + + + +@@ -178,14 +175,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -224,7 +221,7 @@ + + + +- ++ + EXAMPLES + + An example password section would be: +@@ -245,11 +242,11 @@ password required pam_unix.so use_authtok + + + +- ++ + FILES + + +- /etc/security/opasswd ++ /etc/security/opasswd + + Default file with password history + +@@ -257,7 +254,7 @@ password required pam_unix.so use_authtok + + + +- ++ + SEE ALSO + + +@@ -278,11 +275,11 @@ password required pam_unix.so use_authtok + + + +- ++ + AUTHOR + + pam_pwhistory was written by Thorsten Kukuk <kukuk@thkukuk.de> + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_pwhistory/pwhistory.conf.5.xml b/modules/pam_pwhistory/pwhistory.conf.5.xml +index bac5ffed5..2a2dfd3a6 100644 +--- a/modules/pam_pwhistory/pwhistory.conf.5.xml ++++ b/modules/pam_pwhistory/pwhistory.conf.5.xml +@@ -1,25 +1,22 @@ +- +- +- +- ++ + + + pwhistory.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pwhistory.conf + pam_pwhistory configuration file + + +- ++ + + DESCRIPTION + +- pwhistory.conf provides a way to configure the ++ pwhistory.conf provides a way to configure the + default settings for saving the last passwords for each user. + This file is read by the pam_pwhistory module and is the + preferred method over configuring pam_pwhistory directly. +@@ -31,13 +28,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ debug + + + +@@ -50,7 +47,7 @@ + + + +- ++ enforce_for_root + + + +@@ -60,7 +57,7 @@ + + + +- ++ remember=N + + + +@@ -74,7 +71,7 @@ + + + +- ++ retry=N + + + +@@ -85,7 +82,7 @@ + + + +- ++ file=/path/filename + + + +@@ -99,7 +96,7 @@ + + + +- ++ + EXAMPLES + + /etc/security/pwhistory.conf file example: +@@ -111,11 +108,11 @@ file=/tmp/opasswd + + + +- ++ + FILES + + +- /etc/security/pwhistory.conf ++ /etc/security/pwhistory.conf + + the config file for custom options + +@@ -123,7 +120,7 @@ file=/tmp/opasswd + + + +- ++ + SEE ALSO + + +@@ -144,7 +141,7 @@ file=/tmp/opasswd + + + +- ++ + AUTHOR + + pam_pwhistory was written by Thorsten Kukuk. The support for +@@ -152,4 +149,4 @@ file=/tmp/opasswd + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_pwhistory/pwhistory_helper.8.xml b/modules/pam_pwhistory/pwhistory_helper.8.xml +index a03017645..8370a485c 100644 +--- a/modules/pam_pwhistory/pwhistory_helper.8.xml ++++ b/modules/pam_pwhistory/pwhistory_helper.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + pwhistory_helper + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pwhistory_helper + Helper binary that transfers password hashes from passwd or shadow to opasswd + + + +- ++ + pwhistory_helper +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -48,7 +45,7 @@ + + + +- ++ + SEE ALSO + + +@@ -57,7 +54,7 @@ + + + +- ++ + AUTHOR + + Written by Tomas Mraz based on the code originally in +@@ -65,4 +62,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_rhosts/README.xml b/modules/pam_rhosts/README.xml +index 5d3307e73..2345dffda 100644 +--- a/modules/pam_rhosts/README.xml ++++ b/modules/pam_rhosts/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_rhosts.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rhosts-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_rhosts.8.xml" xpointer='xpointer(id("pam_rhosts-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_rhosts/pam_rhosts.8.xml b/modules/pam_rhosts/pam_rhosts.8.xml +index eb96371d2..b8a5c1cbb 100644 +--- a/modules/pam_rhosts/pam_rhosts.8.xml ++++ b/modules/pam_rhosts/pam_rhosts.8.xml +@@ -1,27 +1,24 @@ +- +- +- +- ++ + + + pam_rhosts + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_rhosts + The rhosts PAM module + + + +- ++ + pam_rhosts.so + + + +- ++ + + DESCRIPTION + +@@ -53,12 +50,12 @@ + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -68,7 +65,7 @@ + + + +- ++ silent + + + +@@ -78,7 +75,7 @@ + + + +- ++ superuser=account + + + +@@ -89,14 +86,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -120,7 +117,7 @@ + + + +- ++ + EXAMPLES + + To grant a remote user access by /etc/hosts.equiv +@@ -137,7 +134,7 @@ auth required pam_unix.so + + + +- ++ + SEE ALSO + + +@@ -161,11 +158,11 @@ auth required pam_unix.so + + + +- ++ + AUTHOR + + pam_rhosts was written by Thorsten Kukuk <kukuk@thkukuk.de> + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_rootok/README.xml b/modules/pam_rootok/README.xml +index 6fb58cd04..58f77967b 100644 +--- a/modules/pam_rootok/README.xml ++++ b/modules/pam_rootok/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_rootok.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_rootok-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_rootok.8.xml" xpointer='xpointer(id("pam_rootok-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_rootok/pam_rootok.8.xml b/modules/pam_rootok/pam_rootok.8.xml +index 06457bf5e..a79c073af 100644 +--- a/modules/pam_rootok/pam_rootok.8.xml ++++ b/modules/pam_rootok/pam_rootok.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + pam_rootok + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_rootok + Gain only root access + + + +- ++ + pam_rootok.so +- ++ + debug + + + + +- ++ + + DESCRIPTION + +@@ -38,12 +35,12 @@ + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -54,7 +51,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The , and +@@ -62,7 +59,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -77,7 +74,7 @@ + PAM_AUTH_ERR + + +- The UID is not ++ The UID is not + 0. + + +@@ -85,7 +82,7 @@ + + + +- ++ + EXAMPLES + + In the case of the +@@ -103,7 +100,7 @@ auth required pam_unix.so + + + +- ++ + SEE ALSO + + +@@ -121,11 +118,11 @@ auth required pam_unix.so + + + +- ++ + AUTHOR + + pam_rootok was written by Andrew G. Morgan, <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_securetty/README.xml b/modules/pam_securetty/README.xml +index a8c098a04..70176d758 100644 +--- a/modules/pam_securetty/README.xml ++++ b/modules/pam_securetty/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_securetty.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_securetty-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_securetty.8.xml" xpointer='xpointer(id("pam_securetty-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_securetty/pam_securetty.8.xml b/modules/pam_securetty/pam_securetty.8.xml +index e49d572b2..9038f5b2b 100644 +--- a/modules/pam_securetty/pam_securetty.8.xml ++++ b/modules/pam_securetty/pam_securetty.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + pam_securetty + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_securetty + Limit root login to special devices + + + +- ++ + pam_securetty.so +- ++ + debug + + + + +- ++ + + DESCRIPTION + +@@ -43,23 +40,23 @@ + + + This module has no effect on non-root users and requires that the +- application fills in the PAM_TTY ++ application fills in the PAM_TTY + item correctly. + + + For canonical usage, should be listed as a +- required authentication method +- before any sufficient ++ required authentication method ++ before any sufficient + authentication methods. + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -69,7 +66,7 @@ + + + +- ++ noconsole + + + +@@ -83,14 +80,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -164,7 +161,7 @@ + + + +- ++ + EXAMPLES + + +@@ -174,7 +171,7 @@ auth required pam_unix.so + + + +- ++ + SEE ALSO + + +@@ -192,11 +189,11 @@ auth required pam_unix.so + + + +- ++ + AUTHOR + + pam_securetty was written by Elliot Lee <sopwith@cuc.edu>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_selinux/README.xml b/modules/pam_selinux/README.xml +index 7e1baf555..dc1b5697f 100644 +--- a/modules/pam_selinux/README.xml ++++ b/modules/pam_selinux/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_selinux.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_selinux-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_selinux.8.xml" xpointer='xpointer(id("pam_selinux-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_selinux/pam_selinux.8.xml b/modules/pam_selinux/pam_selinux.8.xml +index 28d465f56..3aa632cf6 100644 +--- a/modules/pam_selinux/pam_selinux.8.xml ++++ b/modules/pam_selinux/pam_selinux.8.xml +@@ -1,54 +1,51 @@ +- +- +- +- ++ + + + pam_selinux + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_selinux + PAM module to set the default security context + + + +- ++ + pam_selinux.so +- ++ + open + +- ++ + close + +- ++ + restore + +- ++ + nottys + +- ++ + debug + +- ++ + verbose + +- ++ + select_context + +- ++ + env_params + +- ++ + use_current_range + + + + +- ++ + DESCRIPTION + + pam_selinux is a PAM module that sets up the default SELinux security +@@ -79,12 +76,12 @@ + + + +- ++ + OPTIONS + + + +- ++ open + + + +@@ -94,7 +91,7 @@ + + + +- ++ close + + + +@@ -104,7 +101,7 @@ + + + +- ++ restore + + + +@@ -117,7 +114,7 @@ + + + +- ++ nottys + + + +@@ -127,7 +124,7 @@ + + + +- ++ debug + + + +@@ -140,7 +137,7 @@ + + + +- ++ verbose + + + +@@ -150,7 +147,7 @@ + + + +- ++ select_context + + + +@@ -161,7 +158,7 @@ + + + +- ++ env_params + + + +@@ -178,7 +175,7 @@ + + + +- ++ use_current_range + + + +@@ -191,14 +188,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -236,7 +233,7 @@ + + + +- ++ + EXAMPLES + + auth required pam_unix.so +@@ -245,7 +242,7 @@ session optional pam_selinux.so + + + +- ++ + SEE ALSO + + +@@ -266,11 +263,11 @@ session optional pam_selinux.so + + + +- ++ + AUTHOR + + pam_selinux was written by Dan Walsh <dwalsh@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_sepermit/README.xml b/modules/pam_sepermit/README.xml +index bb65951c0..a8d31d8c1 100644 +--- a/modules/pam_sepermit/README.xml ++++ b/modules/pam_sepermit/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_sepermit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_sepermit-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_sepermit.8.xml" xpointer='xpointer(id("pam_sepermit-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_sepermit/pam_sepermit.8.xml b/modules/pam_sepermit/pam_sepermit.8.xml +index 5763c3466..791d2bbec 100644 +--- a/modules/pam_sepermit/pam_sepermit.8.xml ++++ b/modules/pam_sepermit/pam_sepermit.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_sepermit + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_sepermit + PAM module to allow/deny login depending on SELinux enforcement state + + + +- ++ + pam_sepermit.so +- ++ + debug + +- ++ + conf=/path/to/config/file + + + + +- ++ + DESCRIPTION + + The pam_sepermit module allows or denies login depending on SELinux +@@ -61,12 +58,12 @@ + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -79,7 +76,7 @@ + + + +- ++ conf=/path/to/config/file + + + +@@ -90,7 +87,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and +@@ -98,7 +95,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -145,11 +142,11 @@ + + + +- ++ + FILES + + +- /etc/security/sepermit.conf ++ /etc/security/sepermit.conf + + Default configuration file + +@@ -157,7 +154,7 @@ + + + +- ++ + EXAMPLES + + auth [success=done ignore=ignore default=bad] pam_sepermit.so +@@ -167,7 +164,7 @@ session required pam_permit.so + + + +- ++ + SEE ALSO + + +@@ -188,11 +185,11 @@ session required pam_permit.so + + + +- ++ + AUTHOR + + pam_sepermit and this manual page were written by Tomas Mraz <tmraz@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_sepermit/sepermit.conf.5.xml b/modules/pam_sepermit/sepermit.conf.5.xml +index 511480f61..ff924ce1a 100644 +--- a/modules/pam_sepermit/sepermit.conf.5.xml ++++ b/modules/pam_sepermit/sepermit.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + sepermit.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -15,7 +12,7 @@ + configuration file for the pam_sepermit module + + +- ++ + DESCRIPTION + + The lines of the configuration file have the following syntax: +@@ -24,7 +21,7 @@ + <user>[:<option>:<option>...] + + +- The user can be specified in the following manner: ++ The user can be specified in the following manner: + + + +@@ -34,13 +31,13 @@ + + + +- a groupname, with @group syntax. ++ a groupname, with @group syntax. + This should not be confused with netgroups. + + + + +- a SELinux user name with %seuser syntax. ++ a SELinux user name with %seuser syntax. + + + +@@ -51,7 +48,7 @@ + + + +- ++ exclusive + + + Only single login session will be allowed for the user +@@ -60,7 +57,7 @@ + + + +- ++ ignore + + + The module will never return PAM_SUCCESS status for the user. +@@ -78,7 +75,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -91,7 +88,7 @@ + + + +- ++ + SEE ALSO + + pam_sepermit8, +@@ -101,10 +98,10 @@ + + + +- ++ + AUTHOR + + pam_sepermit and this manual page were written by Tomas Mraz <tmraz@redhat.com> + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_setquota/README.xml b/modules/pam_setquota/README.xml +index 4eeddecc5..7f5e429d6 100644 +--- a/modules/pam_setquota/README.xml ++++ b/modules/pam_setquota/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_setquota.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_setquota-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_setquota.8.xml" xpointer='xpointer(id("pam_setquota-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_setquota/pam_setquota.8.xml b/modules/pam_setquota/pam_setquota.8.xml +index fe83c8053..41644eeb9 100644 +--- a/modules/pam_setquota/pam_setquota.8.xml ++++ b/modules/pam_setquota/pam_setquota.8.xml +@@ -1,53 +1,51 @@ +- +- +- +- ++ + + + pam_setquota + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_setquota + PAM module to set or modify disk quotas on session start + + + +- ++ + pam_setquota.so +- ++ + fs=/home + +- ++ + overwrite=0 + +- ++ + debug=0 + +- ++ + startuid=1000 + +- ++ + enduid=0 + +- ++ + bsoftlimit=19000 + +- ++ + bhardlimit=20000 + +- ++ + isoftlimit=3000 + +- ++ + ihardlimit=4000 + + + + +- ++ + + DESCRIPTION + +@@ -60,14 +58,14 @@ + + + +- ++ + + OPTIONS + + + + +- ++ fs=/home + + + +@@ -78,7 +76,7 @@ + + + +- ++ overwrite=0 + + + +@@ -91,7 +89,7 @@ + + + +- ++ debug=0 + + + +@@ -103,7 +101,7 @@ + + + +- ++ startuid=1000 + + + +@@ -115,7 +113,7 @@ + + + +- ++ enduid=0 + + + +@@ -128,7 +126,7 @@ + + + +- ++ bsoftlimit=19000 + + + +@@ -142,7 +140,7 @@ + + + +- ++ bhardlimit=20000 + + + +@@ -156,7 +154,7 @@ + + + +- ++ isoftlimit=3000 + + + +@@ -169,7 +167,7 @@ + + + +- ++ ihardlimit=4000 + + + +@@ -184,14 +182,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the module type is provided. + + + +- ++ + RETURN VALUES + + +@@ -255,7 +253,7 @@ + + + +- ++ + EXAMPLES + + A single invocation of `pam_setquota` applies a specific policy to a UID +@@ -270,7 +268,7 @@ + + + +- ++ + SEE ALSO + + +@@ -285,7 +283,7 @@ + + + +- ++ + AUTHOR + + pam_setquota was originally written by +@@ -298,4 +296,4 @@ + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_shells/README.xml b/modules/pam_shells/README.xml +index 154b97b51..c4da1a060 100644 +--- a/modules/pam_shells/README.xml ++++ b/modules/pam_shells/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_shells.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_shells-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_shells.8.xml" xpointer='xpointer(id("pam_shells-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_shells/pam_shells.8.xml b/modules/pam_shells/pam_shells.8.xml +index 15f476717..67d8ecf16 100644 +--- a/modules/pam_shells/pam_shells.8.xml ++++ b/modules/pam_shells/pam_shells.8.xml +@@ -1,27 +1,24 @@ +- +- +- +- ++ + + + pam_shells + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_shells + PAM module to check for valid login shell + + + +- ++ + pam_shells.so + + + +- ++ + + DESCRIPTION + +@@ -35,13 +32,13 @@ + + + +- ++ + + OPTIONS + This module does not recognise any options. + + +- ++ + MODULE TYPES PROVIDED + + The and +@@ -49,7 +46,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -80,7 +77,7 @@ + + + +- ++ + EXAMPLES + + +@@ -89,7 +86,7 @@ auth required pam_shells.so + + + +- ++ + SEE ALSO + + +@@ -107,11 +104,11 @@ auth required pam_shells.so + + + +- ++ + AUTHOR + + pam_shells was written by Erik Troan <ewt@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_stress/README.xml b/modules/pam_stress/README.xml +index 6f94685e1..cc7a1848d 100644 +--- a/modules/pam_stress/README.xml ++++ b/modules/pam_stress/README.xml +@@ -1,31 +1,19 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_stress.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_stress-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_stress.8.xml" xpointer='xpointer(id("pam_stress-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_stress/pam_stress.8.xml b/modules/pam_stress/pam_stress.8.xml +index 98888b1ce..617b7aae1 100644 +--- a/modules/pam_stress/pam_stress.8.xml ++++ b/modules/pam_stress/pam_stress.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_stress + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_stress + The stress-testing PAM module + +@@ -18,42 +15,42 @@ + + + +- ++ + pam_stress.so +- ++ + debug + +- ++ + no_warn + +- ++ + use_first_pass + +- ++ + try_first_pass + +- ++ + rootok + +- ++ + expired + +- ++ + fail_1 + +- ++ + fail_2 + +- ++ + prelim + +- ++ + required + + + + +- ++ + DESCRIPTION + + The pam_stress PAM module is mainly intended to give the impression of failing as a fully +@@ -61,13 +58,13 @@ functioning module might. + + + +- ++ + OPTIONS + + + + +- ++ debug + + + +@@ -79,7 +76,7 @@ functioning module might. + + + +- ++ no_warn + + + +@@ -91,7 +88,7 @@ functioning module might. + + + +- ++ use_first_pass + + + +@@ -103,7 +100,7 @@ functioning module might. + + + +- ++ try_first_pass + + + +@@ -115,7 +112,7 @@ functioning module might. + + + +- ++ rootok + + + +@@ -128,7 +125,7 @@ functioning module might. + + + +- ++ expired + + + +@@ -141,7 +138,7 @@ functioning module might. + + + +- ++ fail_1 + + + +@@ -152,7 +149,7 @@ functioning module might. + + + +- ++ fail_2 + + + +@@ -164,7 +161,7 @@ functioning module might. + + + +- ++ prelim + + + +@@ -175,7 +172,7 @@ functioning module might. + + + +- ++ required + + + +@@ -189,7 +186,7 @@ functioning module might. + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -197,7 +194,7 @@ functioning module might. + + + +- ++ + RETURN VALUES + + +@@ -307,7 +304,7 @@ functioning module might. + + + +- ++ + NOTES + + This module uses the stress_new_pwd data string which tells +@@ -316,7 +313,7 @@ functioning module might. + + + +- ++ + EXAMPLES + + #%PAM-1.0 +@@ -329,7 +326,7 @@ session required pam_stress.so + + + +- ++ + SEE ALSO + + +@@ -344,7 +341,7 @@ session required pam_stress.so + + + +- ++ + AUTHORS + + The pam_stress PAM module was developed by +@@ -353,4 +350,4 @@ session required pam_stress.so + Lucas Ramage <ramage.lucas@protonmail.com>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_succeed_if/README.xml b/modules/pam_succeed_if/README.xml +index c52f00a0f..1c174af05 100644 +--- a/modules/pam_succeed_if/README.xml ++++ b/modules/pam_succeed_if/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_succeed_if.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_succeed_if-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_succeed_if.8.xml" xpointer='xpointer(id("pam_succeed_if-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_succeed_if/pam_succeed_if.8.xml b/modules/pam_succeed_if/pam_succeed_if.8.xml +index 14d939a3e..90fd11454 100644 +--- a/modules/pam_succeed_if/pam_succeed_if.8.xml ++++ b/modules/pam_succeed_if/pam_succeed_if.8.xml +@@ -1,34 +1,30 @@ +- +- +- +- +- ++ + + + + + pam_succeed_if + 8 +- Linux-PAM ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_succeed_if + test account characteristics + + + + +- ++ + pam_succeed_if.so +- flag +- condition ++ flag ++ condition + + + + +- ++ + DESCRIPTION + + pam_succeed_if.so is designed to succeed or fail authentication +@@ -43,7 +39,7 @@ + + + +- ++ + OPTIONS + + The following flags are supported: +@@ -51,13 +47,13 @@ + + + +- ++ debug + + Turns on debugging messages sent to syslog. + + + +- ++ use_uid + + + Evaluate conditions using the account of the user whose UID +@@ -67,13 +63,13 @@ + + + +- ++ quiet + + Don't log failure or success to the system log. + + + +- ++ quiet_fail + + + Don't log failure to the system log. +@@ -81,7 +77,7 @@ + + + +- ++ quiet_success + + + Don't log success to the system log. +@@ -89,7 +85,7 @@ + + + +- ++ audit + + + Log unknown users to the system log. +@@ -112,13 +108,13 @@ + + + +- ++ field < number + + Field has a value numerically less than number. + + + +- ++ field <= number + + + Field has a value numerically less than or equal to number. +@@ -126,7 +122,7 @@ + + + +- ++ field eq number + + + Field has a value numerically equal to number. +@@ -134,7 +130,7 @@ + + + +- ++ field >= number + + + Field has a value numerically greater than or equal to number. +@@ -142,7 +138,7 @@ + + + +- ++ field > number + + + Field has a value numerically greater than number. +@@ -150,7 +146,7 @@ + + + +- ++ field ne number + + + Field has a value numerically different from number. +@@ -158,7 +154,7 @@ + + + +- ++ field = string + + + Field exactly matches the given string. +@@ -166,7 +162,7 @@ + + + +- ++ field != string + + + Field does not match the given string. +@@ -174,49 +170,49 @@ + + + +- ++ field =~ glob + + Field matches the given glob. + + + +- ++ field !~ glob + + Field does not match the given glob. + + + +- ++ field in item:item:... + + Field is contained in the list of items separated by colons. + + + +- ++ field notin item:item:... + + Field is not contained in the list of items separated by colons. + + + +- ++ user ingroup group[:group:....] + + User is in given group(s). + + + +- ++ user notingroup group[:group:....] + + User is not in given group(s). + + + +- ++ user innetgr netgroup + + (user,host) is in given netgroup. + + + +- ++ user notinnetgr group + + (user,host) is not in given netgroup. + +@@ -224,7 +220,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -232,7 +228,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -267,7 +263,7 @@ + + + +- ++ + EXAMPLES + + To emulate the behaviour of pam_wheel, except +@@ -288,7 +284,7 @@ type required othermodule.so arguments... + + + +- ++ + SEE ALSO + + +@@ -300,8 +296,8 @@ type required othermodule.so arguments... + + + +- ++ + AUTHOR + Nalin Dahyabhai <nalin@redhat.com> + +- ++ +\ No newline at end of file +diff --git a/modules/pam_time/README.xml b/modules/pam_time/README.xml +index 6c11eec1f..8a2faa0b8 100644 +--- a/modules/pam_time/README.xml ++++ b/modules/pam_time/README.xml +@@ -1,34 +1,19 @@ +- +- +---> +- +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_time.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_time-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_time.8.xml" xpointer='xpointer(id("pam_time-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_time/pam_time.8.xml b/modules/pam_time/pam_time.8.xml +index a33744ead..1fa60a104 100644 +--- a/modules/pam_time/pam_time.8.xml ++++ b/modules/pam_time/pam_time.8.xml +@@ -1,16 +1,13 @@ +- +- +- +- ++ + + + pam_time + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_time + + PAM module for time control access +@@ -20,22 +17,22 @@ + + + +- ++ + pam_time.so +- ++ + conffile=conf-file + +- ++ + debug + +- ++ + noaudit + + + + + +- ++ + DESCRIPTION + + The pam_time PAM module does not authenticate the user, but instead +@@ -62,13 +59,13 @@ + + + +- ++ + OPTIONS + + + + +- ++ conffile=/path/to/time.conf + + + +@@ -79,7 +76,7 @@ + + + +- ++ debug + + + +@@ -91,7 +88,7 @@ + + + +- ++ noaudit + + + +@@ -103,14 +100,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the type is provided. + + + +- ++ + RETURN VALUES + + +@@ -156,11 +153,11 @@ + + + +- ++ + FILES + + +- /etc/security/time.conf ++ /etc/security/time.conf + + Default configuration file + +@@ -168,7 +165,7 @@ + + + +- ++ + EXAMPLES + + #%PAM-1.0 +@@ -179,7 +176,7 @@ login account required pam_time.so + + + +- ++ + SEE ALSO + + +@@ -194,10 +191,10 @@ login account required pam_time.so + + + +- ++ + AUTHOR + + pam_time was written by Andrew G. Morgan <morgan@kernel.org>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_time/time.conf.5.xml b/modules/pam_time/time.conf.5.xml +index acbe23294..3fe263d5e 100644 +--- a/modules/pam_time/time.conf.5.xml ++++ b/modules/pam_time/time.conf.5.xml +@@ -1,13 +1,10 @@ +- +- +- +- ++ + + + time.conf + 5 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + + +@@ -15,7 +12,7 @@ + configuration file for the pam_time module + + +- ++ + DESCRIPTION + + +@@ -43,9 +40,9 @@ + + + In words, each rule occupies a line, terminated with a newline +- or the beginning of a comment; a '#'. ++ or the beginning of a comment; a '#'. + It contains four fields separated with semicolons, +- ';'. ++ ';'. + + + +@@ -107,7 +104,7 @@ + + + +- ++ + EXAMPLES + + These are some example lines which might be specified in +@@ -131,7 +128,7 @@ games ; * ; !waster ; Wd0000-2400 | Wk1800-0800 + + + +- ++ + SEE ALSO + + pam_time8, +@@ -140,10 +137,10 @@ games ; * ; !waster ; Wd0000-2400 | Wk1800-0800 + + + +- ++ + AUTHOR + + pam_time was written by Andrew G. Morgan <morgan@kernel.org>. + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_timestamp/README.xml b/modules/pam_timestamp/README.xml +index 5b72deb13..fe01080b9 100644 +--- a/modules/pam_timestamp/README.xml ++++ b/modules/pam_timestamp/README.xml +@@ -1,46 +1,31 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_timestamp.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_timestamp-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_timestamp.8.xml" xpointer='xpointer(id("pam_timestamp-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_timestamp/pam_timestamp.8.xml b/modules/pam_timestamp/pam_timestamp.8.xml +index 83e5aea88..a763ad862 100644 +--- a/modules/pam_timestamp/pam_timestamp.8.xml ++++ b/modules/pam_timestamp/pam_timestamp.8.xml +@@ -1,39 +1,36 @@ +- +- +- +- ++ + + + pam_timestamp + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_timestamp + Authenticate using cached successful authentication attempts + + + +- ++ + pam_timestamp.so +- ++ + timestampdir=directory + +- ++ + timestamp_timeout=number + +- ++ + verbose + +- ++ + debug + + + + +- ++ + + DESCRIPTION + +@@ -52,18 +49,18 @@ file as grounds for succeeding. + + + The default encryption hash is taken from the +- HMAC_CRYPTO_ALGO variable from ++ HMAC_CRYPTO_ALGO variable from + /etc/login.defs. + + + +- ++ + + OPTIONS + + + +- ++ timestampdir=directory + + + +@@ -74,7 +71,7 @@ file as grounds for succeeding. + + + +- ++ timestamp_timeout=number + + + +@@ -86,7 +83,7 @@ file as grounds for succeeding. + + + +- ++ verbose + + + +@@ -96,7 +93,7 @@ file as grounds for succeeding. + + + +- ++ debug + + + +@@ -109,7 +106,7 @@ file as grounds for succeeding. + + + +- ++ + MODULE TYPES PROVIDED + + The and +@@ -117,7 +114,7 @@ file as grounds for succeeding. + + + +- ++ + RETURN VALUES + + +@@ -148,7 +145,7 @@ file as grounds for succeeding. + + + +- ++ + NOTES + + Users can get confused when they are not always asked for passwords when +@@ -157,7 +154,7 @@ noticing that it is not being asked for. + + + +- ++ + EXAMPLES + + auth sufficient pam_timestamp.so verbose +@@ -168,11 +165,11 @@ session optional pam_timestamp.so + + + +- ++ + FILES + + +- /var/run/pam_timestamp/... ++ /var/run/pam_timestamp/... + + timestamp files and directories + +@@ -180,7 +177,7 @@ session optional pam_timestamp.so + + + +- ++ + SEE ALSO + + +@@ -198,11 +195,11 @@ session optional pam_timestamp.so + + + +- ++ + AUTHOR + + pam_timestamp was written by Nalin Dahyabhai. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_timestamp/pam_timestamp_check.8.xml b/modules/pam_timestamp/pam_timestamp_check.8.xml +index 3a65d7ef9..f0c095607 100644 +--- a/modules/pam_timestamp/pam_timestamp_check.8.xml ++++ b/modules/pam_timestamp/pam_timestamp_check.8.xml +@@ -1,36 +1,33 @@ +- +- +- +- ++ + + + pam_timestamp_check + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_timestamp_check + Check to see if the default timestamp is valid + + + +- ++ + pam_timestamp_check +- ++ + -k + +- ++ + -d + +- ++ + target_user + + + + +- ++ + + DESCRIPTION + +@@ -40,13 +37,13 @@ see if the default timestamp is valid, or optionally remove it. + + + +- ++ + + OPTIONS + + + +- ++ -k + + + +@@ -57,7 +54,7 @@ see if the default timestamp is valid, or optionally remove it. + + + +- ++ -d + + + +@@ -69,7 +66,7 @@ see if the default timestamp is valid, or optionally remove it. + + + +- ++ target_user + + + +@@ -85,7 +82,7 @@ see if the default timestamp is valid, or optionally remove it. + + + +- ++ + RETURN VALUES + + +@@ -147,7 +144,7 @@ see if the default timestamp is valid, or optionally remove it. + + + +- ++ + NOTES + + Users can get confused when they are not always asked for passwords when +@@ -156,7 +153,7 @@ noticing that it is not being asked for. + + + +- ++ + EXAMPLES + + auth sufficient pam_timestamp.so verbose +@@ -167,11 +164,11 @@ session optional pam_timestamp.so + + + +- ++ + FILES + + +- /var/run/sudo/... ++ /var/run/sudo/... + + timestamp files and directories + +@@ -179,7 +176,7 @@ session optional pam_timestamp.so + + + +- ++ + SEE ALSO + + +@@ -197,11 +194,11 @@ session optional pam_timestamp.so + + + +- ++ + AUTHOR + + pam_timestamp was written by Nalin Dahyabhai. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_tty_audit/README.xml b/modules/pam_tty_audit/README.xml +index 4dad6bbe7..95b851cba 100644 +--- a/modules/pam_tty_audit/README.xml ++++ b/modules/pam_tty_audit/README.xml +@@ -1,41 +1,31 @@ +- +- ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_tty_audit.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_tty_audit-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_tty_audit.8.xml" xpointer='xpointer(id("pam_tty_audit-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_tty_audit/pam_tty_audit.8.xml b/modules/pam_tty_audit/pam_tty_audit.8.xml +index 1c0ba5c4e..b46bbf7b6 100644 +--- a/modules/pam_tty_audit/pam_tty_audit.8.xml ++++ b/modules/pam_tty_audit/pam_tty_audit.8.xml +@@ -1,33 +1,30 @@ +- +- +- +- ++ + + + pam_tty_audit + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_tty_audit + Enable or disable TTY auditing for specified users + + + +- ++ + pam_tty_audit.so +- ++ + disable=patterns + +- ++ + enable=patterns + + + + +- ++ + DESCRIPTION + + The pam_tty_audit PAM module is used to enable or disable TTY auditing. +@@ -35,12 +32,12 @@ + + + +- ++ + OPTIONS + + + +- ++ disable=patterns + + + +@@ -53,7 +50,7 @@ + + + +- ++ enable=patterns + + + +@@ -66,7 +63,7 @@ + + + +- ++ open_only + + + +@@ -79,7 +76,7 @@ + + + +- ++ log_passwd + + + +@@ -93,14 +90,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + +- Only the session type is supported. ++ Only the session type is supported. + + + +- ++ + RETURN VALUES + + +@@ -125,7 +122,7 @@ + + + +- ++ + NOTES + + When TTY auditing is enabled, it is inherited by all processes started by +@@ -158,7 +155,7 @@ + + + +- ++ + EXAMPLES + + Audit all administrative actions. +@@ -168,7 +165,7 @@ session required pam_tty_audit.so disable=* enable=root + + + +- ++ + SEE ALSO + + +@@ -186,14 +183,14 @@ session required pam_tty_audit.so disable=* enable=root + + + +- ++ + AUTHOR + +- pam_tty_audit was written by Miloslav Trmač ++ pam_tty_audit was written by Miloslav Trmač + <mitr@redhat.com>. + The log_passwd option was added by Richard Guy Briggs + <rgb@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_umask/README.xml b/modules/pam_umask/README.xml +index 9afbe5431..d2b82d10d 100644 +--- a/modules/pam_umask/README.xml ++++ b/modules/pam_umask/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_umask.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_umask-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_umask.8.xml" xpointer='xpointer(id("pam_umask-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_umask/pam_umask.8.xml b/modules/pam_umask/pam_umask.8.xml +index 7c4a310b7..052766728 100644 +--- a/modules/pam_umask/pam_umask.8.xml ++++ b/modules/pam_umask/pam_umask.8.xml +@@ -1,42 +1,39 @@ +- +- +- +- ++ + + + pam_umask + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_umask + PAM module to set the file mode creation mask + + + +- ++ + pam_umask.so +- ++ + debug + +- ++ + silent + +- ++ + usergroups + +- ++ + nousergroups + +- ++ + umask=mask + + + + +- ++ + + DESCRIPTION + +@@ -81,7 +78,7 @@ + + + +- ++ + + OPTIONS + +@@ -89,7 +86,7 @@ + + + +- ++ debug + + + +@@ -100,7 +97,7 @@ + + + +- ++ silent + + + +@@ -111,20 +108,20 @@ + + + +- ++ usergroups + + + + If the user is not root and the username is the same as + primary group name, the umask group bits are set to be the +- same as owner bits (examples: 022 -> 002, 077 -> 007). ++ same as owner bits (examples: 022 -> 002, 077 -> 007). + + + + + + +- ++ nousergroups + + + +@@ -137,7 +134,7 @@ + + + +- ++ umask=mask + + + +@@ -153,14 +150,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + + Only the type is provided. + + + +- ++ + RETURN VALUES + + +@@ -225,7 +222,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/login to +@@ -236,7 +233,7 @@ + + + +- ++ + SEE ALSO + + +@@ -251,11 +248,11 @@ + + + +- ++ + AUTHOR + + pam_umask was written by Thorsten Kukuk <kukuk@thkukuk.de>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_unix/README.xml b/modules/pam_unix/README.xml +index 7fd340b33..49a65946b 100644 +--- a/modules/pam_unix/README.xml ++++ b/modules/pam_unix/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_unix.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_unix-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_unix.8.xml" xpointer='xpointer(id("pam_unix-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml +index 9f9c8185f..dfc04274c 100644 +--- a/modules/pam_unix/pam_unix.8.xml ++++ b/modules/pam_unix/pam_unix.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + pam_unix + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_unix + Module for traditional password authentication + + + +- ++ + pam_unix.so +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -42,7 +39,7 @@ + shadow elements: expire, last_change, max_change, + min_change, warn_change. In the case of the latter, it may offer advice + to the user on changing their password or, through the +- PAM_AUTHTOKEN_REQD return, delay ++ PAM_AUTHTOKEN_REQD return, delay + giving service to the user until they have established a new password. + The entries listed above are documented in the + shadow5 +@@ -89,7 +86,7 @@ + + The password component of this module performs the task of updating + the user's password. The default encryption hash is taken from the +- ENCRYPT_METHOD variable from ++ ENCRYPT_METHOD variable from + /etc/login.defs + + +@@ -107,13 +104,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ debug + + + +@@ -127,7 +124,7 @@ + + + +- ++ audit + + + +@@ -138,7 +135,7 @@ + + + +- ++ quiet + + + +@@ -153,7 +150,7 @@ + + + +- ++ nullok + + + +@@ -165,7 +162,7 @@ + + + +- ++ nullresetok + + + +@@ -178,7 +175,7 @@ + + + +- ++ try_first_pass + + + +@@ -190,7 +187,7 @@ + + + +- ++ use_first_pass + + + +@@ -203,7 +200,7 @@ + + + +- ++ nodelay + + + +@@ -216,7 +213,7 @@ + + + +- ++ use_authtok + + + +@@ -230,7 +227,7 @@ + + + +- ++ authtok_type=type + + + +@@ -242,7 +239,7 @@ + + + +- ++ nis + + + +@@ -252,7 +249,7 @@ + + + +- ++ remember=n + + + +@@ -269,7 +266,7 @@ + + + +- ++ shadow + + + +@@ -279,7 +276,7 @@ + + + +- ++ md5 + + + +@@ -290,7 +287,7 @@ + + + +- ++ bigcrypt + + + +@@ -301,7 +298,7 @@ + + + +- ++ sha256 + + + +@@ -315,7 +312,7 @@ + + + +- ++ sha512 + + + +@@ -329,7 +326,7 @@ + + + +- ++ blowfish + + + +@@ -343,7 +340,7 @@ + + + +- ++ gost_yescrypt + + + +@@ -357,7 +354,7 @@ + + + +- ++ yescrypt + + + +@@ -371,7 +368,7 @@ + + + +- ++ rounds=n + + + +@@ -384,7 +381,7 @@ + + + +- ++ broken_shadow + + + +@@ -395,7 +392,7 @@ + + + +- ++ minlen=n + + + +@@ -407,7 +404,7 @@ + + + +- ++ no_pass_expiry + + + +@@ -418,9 +415,9 @@ + meaning that other authentication source or method succeeded. + The example can be public key authentication in + sshd. The module will return +- PAM_SUCCESS instead of eventual +- PAM_NEW_AUTHTOK_REQD or +- PAM_AUTHTOK_EXPIRED. ++ PAM_SUCCESS instead of eventual ++ PAM_NEW_AUTHTOK_REQD or ++ PAM_AUTHTOK_EXPIRED. + + + +@@ -432,7 +429,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -440,7 +437,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -454,7 +451,7 @@ + + + +- ++ + EXAMPLES + + An example usage for /etc/pam.d/login +@@ -473,7 +470,7 @@ session required pam_unix.so + + + +- ++ + SEE ALSO + + +@@ -491,11 +488,11 @@ session required pam_unix.so + + + +- ++ + AUTHOR + + pam_unix was written by various people. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_unix/unix_chkpwd.8.xml b/modules/pam_unix/unix_chkpwd.8.xml +index a10dbe330..ca0fa109f 100644 +--- a/modules/pam_unix/unix_chkpwd.8.xml ++++ b/modules/pam_unix/unix_chkpwd.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + unix_chkpwd + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + unix_chkpwd + Helper binary that verifies the password of the current user + + + +- ++ + unix_chkpwd +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -48,7 +45,7 @@ + + + +- ++ + SEE ALSO + + +@@ -57,11 +54,11 @@ + + + +- ++ + AUTHOR + + Written by Andrew Morgan and other various people. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_unix/unix_update.8.xml b/modules/pam_unix/unix_update.8.xml +index 6c7467b90..1a9686529 100644 +--- a/modules/pam_unix/unix_update.8.xml ++++ b/modules/pam_unix/unix_update.8.xml +@@ -1,30 +1,27 @@ +- +- +- +- ++ + + + unix_update + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + unix_update + Helper binary that updates the password of a given user + + + +- ++ + unix_update +- ++ + ... + + + + +- ++ + + DESCRIPTION + +@@ -48,7 +45,7 @@ + + + +- ++ + SEE ALSO + + +@@ -57,11 +54,11 @@ + + + +- ++ + AUTHOR + + Written by Tomas Mraz and other various people. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_userdb/README.xml b/modules/pam_userdb/README.xml +index b22c09e74..4e8f8ee7a 100644 +--- a/modules/pam_userdb/README.xml ++++ b/modules/pam_userdb/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_userdb.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_userdb-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_userdb.8.xml" xpointer='xpointer(id("pam_userdb-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_userdb/pam_userdb.8.xml b/modules/pam_userdb/pam_userdb.8.xml +index bce92850a..0f9641024 100644 +--- a/modules/pam_userdb/pam_userdb.8.xml ++++ b/modules/pam_userdb/pam_userdb.8.xml +@@ -1,54 +1,51 @@ +- +- +- +- ++ + + + pam_userdb + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_userdb + PAM module to authenticate against a db database + + + +- ++ + pam_userdb.so +- ++ + db=/path/database + +- ++ + debug + +- ++ + crypt=[crypt|none] + +- ++ + icase + +- ++ + dump + +- ++ + try_first_pass + +- ++ + use_first_pass + +- ++ + unknown_ok + +- ++ + key_only + + + + +- ++ + + DESCRIPTION + +@@ -60,13 +57,13 @@ + + + +- ++ + + OPTIONS + + + +- ++ crypt=[crypt|none] + + + +@@ -82,13 +79,13 @@ + + + +- ++ db=/path/database + + + + Use the /path/database database for + performing lookup. There is no default; the module will +- return PAM_IGNORE if no ++ return PAM_IGNORE if no + database is provided. Note that the path to the database file + should be specified without the .db suffix. + +@@ -96,7 +93,7 @@ + + + +- ++ debug + + + +@@ -107,7 +104,7 @@ + + + +- ++ dump + + + +@@ -118,7 +115,7 @@ + + + +- ++ icase + + + +@@ -131,7 +128,7 @@ + + + +- ++ try_first_pass + + + +@@ -146,7 +143,7 @@ + + + +- ++ use_first_pass + + + +@@ -161,7 +158,7 @@ + + + +- ++ unknown_ok + + + +@@ -174,7 +171,7 @@ + + + +- ++ key_only + + + +@@ -191,7 +188,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + The and module +@@ -199,7 +196,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -259,14 +256,14 @@ + + + +- ++ + EXAMPLES + + auth sufficient pam_userdb.so icase db=/etc/dbtest + + + +- ++ + SEE ALSO + + +@@ -284,11 +281,11 @@ auth sufficient pam_userdb.so icase db=/etc/dbtest + + + +- ++ + AUTHOR + + pam_userdb was written by Cristian Gafton >gafton@redhat.com<. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_usertype/README.xml b/modules/pam_usertype/README.xml +index 585504654..7faf549e2 100644 +--- a/modules/pam_usertype/README.xml ++++ b/modules/pam_usertype/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_usertype.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_usertype-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_usertype.8.xml" xpointer='xpointer(id("pam_usertype-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_usertype/pam_usertype.8.xml b/modules/pam_usertype/pam_usertype.8.xml +index d9307ba3a..87ad0796c 100644 +--- a/modules/pam_usertype/pam_usertype.8.xml ++++ b/modules/pam_usertype/pam_usertype.8.xml +@@ -1,31 +1,27 @@ +- +- +- +- +- ++ + + pam_usertype + 8 +- Linux-PAM ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_usertype + check if the authenticated user is a system or regular account + + + + +- ++ + pam_usertype.so +- flag +- condition ++ flag ++ condition + + + + +- ++ + DESCRIPTION + + pam_usertype.so is designed to succeed or fail authentication +@@ -42,7 +38,7 @@ + + + +- ++ + OPTIONS + + The following flags are supported: +@@ -50,7 +46,7 @@ + + + +- ++ use_uid + + + Evaluate conditions using the account of the user whose UID +@@ -60,7 +56,7 @@ + + + +- ++ audit + + + Log unknown users to the system log. +@@ -75,13 +71,13 @@ + + + +- ++ issystem + + Succeed if the user is a system user. + + + +- ++ isregular + + Succeed if the user is a regular user. + +@@ -89,7 +85,7 @@ + + + +- ++ + MODULE TYPES PROVIDED + + All module types (, , +@@ -97,7 +93,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -170,7 +166,7 @@ + + + +- ++ + EXAMPLES + + Skip remaining modules if the user is a system user: +@@ -180,7 +176,7 @@ account sufficient pam_usertype.so issystem + + + +- ++ + SEE ALSO + + +@@ -192,8 +188,8 @@ account sufficient pam_usertype.so issystem + + + +- ++ + AUTHOR + Pavel Březina <pbrezina@redhat.com> + +- ++ +\ No newline at end of file +diff --git a/modules/pam_warn/README.xml b/modules/pam_warn/README.xml +index 4367c28f4..56093f805 100644 +--- a/modules/pam_warn/README.xml ++++ b/modules/pam_warn/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_warn.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_warn-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_warn.8.xml" xpointer='xpointer(id("pam_warn-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_warn/pam_warn.8.xml b/modules/pam_warn/pam_warn.8.xml +index 1764ec924..a20c5f718 100644 +--- a/modules/pam_warn/pam_warn.8.xml ++++ b/modules/pam_warn/pam_warn.8.xml +@@ -1,25 +1,22 @@ +- +- +- +- ++ + + + pam_warn + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + +- ++ + pam_warn + PAM module which logs all PAM items if called + + +- ++ + pam_warn.so + + + +- ++ + DESCRIPTION + + pam_warn is a PAM module that logs the service, terminal, user, +@@ -28,17 +25,17 @@ + syslog3 + . The items are not probed for, but instead obtained + from the standard PAM items. The module always returns +- PAM_IGNORE, indicating that it ++ PAM_IGNORE, indicating that it + does not want to affect the authentication process. + + + +- ++ + OPTIONS + This module does not recognise any options. + + +- ++ + MODULE TYPES PROVIDED + + The , , +@@ -47,7 +44,7 @@ + + + +- ++ + RETURN VALUES + + +@@ -61,7 +58,7 @@ + + + +- ++ + EXAMPLES + + #%PAM-1.0 +@@ -80,7 +77,7 @@ other session required pam_deny.so + + + +- ++ + SEE ALSO + + +@@ -95,11 +92,11 @@ other session required pam_deny.so + + + +- ++ + AUTHOR + + pam_warn was written by Andrew G. Morgan <morgan@kernel.org>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_wheel/README.xml b/modules/pam_wheel/README.xml +index 9e33d7ff2..e40c46e84 100644 +--- a/modules/pam_wheel/README.xml ++++ b/modules/pam_wheel/README.xml +@@ -1,41 +1,27 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_wheel.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_wheel-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_wheel.8.xml" xpointer='xpointer(id("pam_wheel-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_wheel/pam_wheel.8.xml b/modules/pam_wheel/pam_wheel.8.xml +index ee8c7d269..af0fd6199 100644 +--- a/modules/pam_wheel/pam_wheel.8.xml ++++ b/modules/pam_wheel/pam_wheel.8.xml +@@ -1,45 +1,42 @@ +- +- +- +- ++ + + + pam_wheel + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_wheel + Only permit root access to members of group wheel + + + +- ++ + pam_wheel.so +- ++ + debug + +- ++ + deny + +- ++ + group=name + +- ++ + root_only + +- ++ + trust + +- ++ + use_uid + + + + +- ++ + DESCRIPTION + + The pam_wheel PAM module is used to enforce the so-called +@@ -47,16 +44,16 @@ + access to the target user if the applicant user is a member of the + wheel group. If no group with this name exist, + the module is using the group with the group-ID +- 0. ++ 0. + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -66,7 +63,7 @@ + + + +- ++ deny + + + +@@ -81,7 +78,7 @@ + + + +- ++ group=name + + + +@@ -93,7 +90,7 @@ + + + +- ++ root_only + + + +@@ -104,7 +101,7 @@ + + + +- ++ trust + + + +@@ -118,7 +115,7 @@ + + + +- ++ use_uid + + + +@@ -131,15 +128,15 @@ + + + +- ++ + MODULE TYPES PROVIDED + +- The auth and +- account module types are provided. ++ The auth and ++ account module types are provided. + + + +- ++ + RETURN VALUES + + +@@ -204,7 +201,7 @@ + + + +- ++ + EXAMPLES + + The root account gains access by default (rootok), only wheel +@@ -218,7 +215,7 @@ su auth required pam_unix.so + + + +- ++ + SEE ALSO + + +@@ -233,11 +230,11 @@ su auth required pam_unix.so + + + +- ++ + AUTHOR + + pam_wheel was written by Cristian Gafton <gafton@redhat.com>. + + + +- ++ +\ No newline at end of file +diff --git a/modules/pam_xauth/README.xml b/modules/pam_xauth/README.xml +index adefbd98e..04fc24683 100644 +--- a/modules/pam_xauth/README.xml ++++ b/modules/pam_xauth/README.xml +@@ -1,46 +1,31 @@ +- +- +---> +-]> ++
+ +-
+- +- ++ + + +- <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" +- href="pam_xauth.8.xml" xpointer='xpointer(//refnamediv[@id = "pam_xauth-name"]/*)'/> ++ <xi:include xmlns:xi="http://www.w3.org/2001/XInclude" href="pam_xauth.8.xml" xpointer='xpointer(id("pam_xauth-name")/*)'/> + + +- ++ + +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +
+- ++ +
+ +-
++
+\ No newline at end of file +diff --git a/modules/pam_xauth/pam_xauth.8.xml b/modules/pam_xauth/pam_xauth.8.xml +index 08c06cf84..f5fc5a3c3 100644 +--- a/modules/pam_xauth/pam_xauth.8.xml ++++ b/modules/pam_xauth/pam_xauth.8.xml +@@ -1,39 +1,36 @@ +- +- +- +- ++ + + + pam_xauth + 8 +- Linux-PAM Manual ++ Linux-PAM ++ Linux-PAM Manual + + +- ++ + pam_xauth + PAM module to forward xauth keys between users + + + +- ++ + pam_xauth.so +- ++ + debug + +- ++ + xauthpath=/path/to/xauth + +- ++ + systemuser=UID + +- ++ + targetuser=UID + + + + +- ++ + DESCRIPTION + + The pam_xauth PAM module is designed to forward xauth keys +@@ -81,25 +78,25 @@ + If a user has a .xauth/export file, the user will + only forward cookies to users listed in the file. If there is no + ~/.xauth/export file, and the invoking user is +- not root, the user will forward cookies ++ not root, the user will forward cookies + to any other user. If there is no ~/.xauth/export +- file, and the invoking user is root, +- the user will not forward cookies to ++ file, and the invoking user is root, ++ the user will not forward cookies to + other users. + + + Both the import and export files support wildcards (such as +- *). Both the import and export files ++ *). Both the import and export files + can be empty, signifying that no users are allowed. + + + +- ++ + OPTIONS + + + +- ++ debug + + + +@@ -109,7 +106,7 @@ + + + +- ++ xauthpath=/path/to/xauth + + + +@@ -122,7 +119,7 @@ + + + +- ++ systemuser=UID + + + +@@ -135,7 +132,7 @@ + + + +- ++ targetuser=UID + + + +@@ -147,14 +144,14 @@ + + + +- ++ + MODULE TYPES PROVIDED + +- Only the session type is provided. ++ Only the session type is provided. + + + +- ++ + RETURN VALUES + + +@@ -205,7 +202,7 @@ + + + +- ++ + EXAMPLES + + Add the following line to /etc/pam.d/su to +@@ -216,10 +213,10 @@ session optional pam_xauth.so + + + +- ++ + IMPLEMENTATION DETAILS + +- pam_xauth will work only if it is ++ pam_xauth will work only if it is + used from a setuid application in which the + getuid() call returns the id of the user + running the application, and for which PAM can supply the name +@@ -247,17 +244,17 @@ session optional pam_xauth.so + + + +- ++ + FILES + + +- ~/.xauth/import ++ ~/.xauth/import + + XXX + + + +- ~/.xauth/export ++ ~/.xauth/export + + XXX + +@@ -266,7 +263,7 @@ session optional pam_xauth.so + + + +- ++ + SEE ALSO + + +@@ -281,7 +278,7 @@ session optional pam_xauth.so + + + +- ++ + AUTHOR + + pam_xauth was written by Nalin Dahyabhai <nalin@redhat.com>, +@@ -290,4 +287,4 @@ session optional pam_xauth.so + + + +- ++ +\ No newline at end of file diff --git a/pam-git.diff b/pam-git.diff index 3f05e3c..813aa2d 100644 --- a/pam-git.diff +++ b/pam-git.diff @@ -3,28 +3,66 @@ index 21af8c4c..aa99927e 100644 --- a/README +++ b/README @@ -6,7 +6,7 @@ NOTES: - + How to use it is as follows: - + -Please look at the ci/install_dependencies.sh for the necessary +Please look at the ci/install-dependencies.sh for the necessary prerequisite packages to be able to build the Linux-PAM. The script is targeted at Debian based Linux distributions so the package names and availability might differ on other distributions. diff --git a/configure.ac b/configure.ac -index c06bc7dd..639fc1ad 100644 +index c06bc7dd..2f74d1b4 100644 --- a/configure.ac +++ b/configure.ac -@@ -259,6 +259,8 @@ AC_MSG_RESULT([Defining \$ISA to "$ISA"]) +@@ -243,6 +243,29 @@ if test x"$enable_debug" = x"yes" ; then + [lots of stuff gets written to /var/run/pam-debug.log]) + fi + ++AC_ARG_ENABLE(html_stylesheet, ++ AS_HELP_STRING([--enable-html-stylesheet=FILE],[html stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl@:>@]), ++ HTML_STYLESHEET=$enableval, HTML_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl) ++AC_SUBST(HTML_STYLESHEET) ++ ++AC_ARG_ENABLE(txt_stylesheet, ++ AS_HELP_STRING([--enable-txt-stylesheet=FILE],[text stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl@:>@]), ++ TXT_STYLESHEET=$enableval, TXT_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl) ++AC_SUBST(TXT_STYLESHEET) ++# It has to be TXT_STYLESHEET otherwise a html tree will be generated while generating all README files. ++sed "s+HTML_STYLESHEET+$TXT_STYLESHEET+g" doc/custom-html.xsl ++ ++AC_ARG_ENABLE(pdf_stylesheet, ++ AS_HELP_STRING([--enable-pdf-stylesheet=FILE],[pdf stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl@:>@]), ++ PDF_STYLESHEET=$enableval, PDF_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl) ++AC_SUBST(PDF_STYLESHEET) ++ ++AC_ARG_ENABLE(man_stylesheet, ++ AS_HELP_STRING([--enable-man-stylesheet=FILE],[man stylesheet path @<:@default=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl@:>@]), ++ MAN_STYLESHEET=$enableval, MAN_STYLESHEET=http://docbook.sourceforge.net/release/xsl/current/manpages/profile-docbook.xsl) ++AC_SUBST(MAN_STYLESHEET) ++sed "s+MAN_STYLESHEET+$MAN_STYLESHEET+g" doc/custom-man.xsl ++ + AC_ARG_ENABLE(securedir, + AS_HELP_STRING([--enable-securedir=DIR],[path to location of PAMs @<:@default=$libdir/security@:>@]), + SECUREDIR=$enableval, SECUREDIR=$libdir/security) +@@ -259,6 +282,8 @@ AC_MSG_RESULT([Defining \$ISA to "$ISA"]) AC_ARG_ENABLE(sconfigdir, AS_HELP_STRING([--enable-sconfigdir=DIR],[path to module conf files @<:@default=$sysconfdir/security@:>@]), SCONFIGDIR=$enableval, SCONFIGDIR=$sysconfdir/security) +AC_DEFINE_UNQUOTED([SCONFIGDIR], ["$SCONFIGDIR"], + [Directory for PAM modules system configuration files]) AC_SUBST(SCONFIGDIR) - + AC_ARG_ENABLE(pamlocking, -@@ -507,9 +509,11 @@ AC_ARG_ENABLE([vendordir], +@@ -295,6 +320,7 @@ if test x$with_mailspool != x ; then + else + AC_RUN_IFELSE([AC_LANG_SOURCE([[ + #include ++#include + int main() { + #ifdef _PATH_MAILDIR + exit(0); +@@ -507,9 +533,11 @@ AC_ARG_ENABLE([vendordir], if test -n "$enable_vendordir"; then AC_DEFINE_UNQUOTED([VENDORDIR], ["$enable_vendordir"], [Directory for distribution provided configuration files]) @@ -37,7 +75,81 @@ index c06bc7dd..639fc1ad 100644 + STRINGPARAM_VENDORDIR="--stringparam profile.condition 'without_vendordir'" fi AC_SUBST([STRINGPARAM_VENDORDIR]) - + +@@ -628,11 +656,6 @@ test -n "$opt_uidmin" || + opt_uidmin=1000 + AC_DEFINE_UNQUOTED(PAM_USERTYPE_UIDMIN, $opt_uidmin, [Minimum regular user uid.]) + +-AC_ARG_WITH([sysuidmin], AS_HELP_STRING([--with-sysuidmin=],[default value for system user min uid (101)]), opt_sysuidmin=$withval) +-test -n "$opt_sysuidmin" || +- opt_sysuidmin=101 +-AC_DEFINE_UNQUOTED(PAM_USERTYPE_SYSUIDMIN, $opt_sysuidmin, [Minimum system user uid.]) +- + AC_ARG_WITH([kernel-overflow-uid], AS_HELP_STRING([--with-kernel-overflow-uid=],[kernel overflow uid, default (uint16_t)-2=65534]), opt_kerneloverflowuid=$withval) + test -n "$opt_kerneloverflowuid" || + opt_kerneloverflowuid=65534 +diff --git a/doc/adg/Makefile.am b/doc/adg/Makefile.am +index 77bd7a99..b795b1a4 100644 +--- a/doc/adg/Makefile.am ++++ b/doc/adg/Makefile.am +@@ -21,7 +21,7 @@ if ENABLE_GENERATE_PDF + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ +- http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< > Linux-PAM_ADG.fo ++ $(PDF_STYLESHEET) $< > Linux-PAM_ADG.fo + $(FO2PDF) Linux-PAM_ADG.fo $@ + else + echo "No fo2pdf processor installed, skip PDF generation" +@@ -33,7 +33,7 @@ Linux-PAM_ADG.txt: $(XMLS) $(DEP_XMLS) + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ +- http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< | $(BROWSER) > $@ ++ $(TXT_STYLESHEET) $< | $(BROWSER) > $@ + + html/Linux-PAM_ADG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +@@ -46,7 +46,7 @@ html/Linux-PAM_ADG.html: $(XMLS) $(DEP_XMLS) + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ + --stringparam chunker.output.encoding UTF-8 \ +- http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< ++ $(HTML_STYLESHEET) $< + + distclean-local: + -rm -rf html Linux-PAM_ADG.txt Linux-PAM_ADG.pdf +diff --git a/doc/custom-html.xsl b/doc/custom-html.xsl.in +similarity index 87% +rename from doc/custom-html.xsl +rename to doc/custom-html.xsl.in +index fdd5df7d..b2eaf150 100644 +--- a/doc/custom-html.xsl ++++ b/doc/custom-html.xsl.in +@@ -3,7 +3,7 @@ + xmlns:ss="http://docbook.sf.net/xmlns/string.subst/1.0" + xmlns:exsl="http://exslt.org/common" version="1.0"> + +- ++ + + + +diff --git a/doc/custom-man.xsl b/doc/custom-man.xsl.in +similarity index 77% +rename from doc/custom-man.xsl +rename to doc/custom-man.xsl.in +index a3408e6c..258627bf 100644 +--- a/doc/custom-man.xsl ++++ b/doc/custom-man.xsl.in +@@ -1,6 +1,6 @@ + + +- ++ + + + diff --git a/doc/man/Makefile.am b/doc/man/Makefile.am index 78c891df..c6fd73db 100644 --- a/doc/man/Makefile.am @@ -48,7 +160,7 @@ index 78c891df..c6fd73db 100644 misc_conv.3.xml pam_misc_paste_env.3.xml pam_misc_drop_env.3.xml \ - pam_misc_setenv.3.xml + pam_misc_setenv.3.xml pam_xauth_data.3.xml - + if ENABLE_REGENERATE_MAN PAM.8: pam.8 diff --git a/doc/man/pam.8.xml b/doc/man/pam.8.xml @@ -73,6 +185,81 @@ index 464af0e5..8eef665a 100644 +diff --git a/doc/mwg/Makefile.am b/doc/mwg/Makefile.am +index 2bbb2d0b..688e6cb3 100644 +--- a/doc/mwg/Makefile.am ++++ b/doc/mwg/Makefile.am +@@ -21,7 +21,7 @@ if ENABLE_GENERATE_PDF + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ +- http://docbook.sourceforge.net/release/xsl/current/fo/docbook.xsl $< > Linux-PAM_MWG.fo ++ $(PDF_STYLESHEET) $< > Linux-PAM_MWG.fo + $(FO2PDF) Linux-PAM_MWG.fo $@ + else + echo "No fo2pdf processor installed, skip PDF generation" +@@ -33,7 +33,7 @@ Linux-PAM_MWG.txt: $(XMLS) $(DEP_XMLS) + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ +- http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< | $(BROWSER) > $@ ++ $(TXT_STYLESHEET) $< | $(BROWSER) > $@ + + html/Linux-PAM_MWG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +@@ -46,7 +46,7 @@ html/Linux-PAM_MWG.html: $(XMLS) $(DEP_XMLS) + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 3 --xinclude --nonet \ + --stringparam chunker.output.encoding UTF-8 \ +- http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< ++ $(HTML_STYLESHEET) $< + + distclean-local: + -rm -rf html Linux-PAM_MWG.txt Linux-PAM_MWG.pdf +diff --git a/doc/sag/Linux-PAM_SAG.xml b/doc/sag/Linux-PAM_SAG.xml +index 0f33e0f6..2adaef7d 100644 +--- a/doc/sag/Linux-PAM_SAG.xml ++++ b/doc/sag/Linux-PAM_SAG.xml +@@ -408,6 +408,8 @@ session required pam_warn.so + href="pam_exec.xml"/> + ++ + + Linux-PAM_SAG.fo ++ $(PDF_STYLESHEET) $< > Linux-PAM_SAG.fo + $(FO2PDF) Linux-PAM_SAG.fo $@ + else + echo "No fo2pdf processor installed, skip PDF generation" +@@ -34,7 +34,7 @@ Linux-PAM_SAG.txt: $(XMLS) $(DEP_XMLS) + --stringparam section.autolabel 1 \ + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 2 --xinclude --nonet \ +- http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl $< | $(BROWSER) > $@ ++ $(TXT_STYLESHEET) $< | $(BROWSER) > $@ + + html/Linux-PAM_SAG.html: $(XMLS) $(DEP_XMLS) + @test -d html || mkdir -p html +@@ -47,7 +47,7 @@ html/Linux-PAM_SAG.html: $(XMLS) $(DEP_XMLS) + --stringparam section.label.includes.component.label 1 \ + --stringparam toc.max.depth 2 --xinclude --nonet \ + --stringparam chunker.output.encoding UTF-8 \ +- http://docbook.sourceforge.net/release/xsl/current/html/chunk.xsl $< ++ $(HTML_STYLESHEET) $< + + distclean-local: + -rm -rf html Linux-PAM_SAG.txt Linux-PAM_SAG.pdf diff --git a/examples/Makefile.am b/examples/Makefile.am index 722ec686..c4c3c261 100644 --- a/examples/Makefile.am @@ -80,7 +267,7 @@ index 722ec686..c4c3c261 100644 @@ -11,4 +11,4 @@ AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ LDADD = $(top_builddir)/libpam/libpam.la \ $(top_builddir)/libpam_misc/libpam_misc.la - + -noinst_PROGRAMS = xsh vpass blank check_user +noinst_PROGRAMS = xsh vpass blank check_user tty_conv diff --git a/examples/tty_conv.c b/examples/tty_conv.c @@ -278,27 +465,128 @@ index ef4dca0c..5b34fc17 100644 + bail_out(pamh,1,retcode,"pam_set_item(PAM_TTY)"); } } - + diff --git a/libpam/Makefile.am b/libpam/Makefile.am index 55222afc..389d5d02 100644 --- a/libpam/Makefile.am +++ b/libpam/Makefile.am @@ -21,7 +21,7 @@ noinst_HEADERS = pam_prelude.h pam_private.h pam_tokens.h \ include/pam_inline.h include/test_assert.h - + libpam_la_LDFLAGS = -no-undefined -version-info 85:1:85 -libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ +libpam_la_LIBADD = @LIBAUDIT@ $(LIBPRELUDE_LIBS) $(ECONF_LIBS) @LIBDL@ @LTLIBINTL@ - + if HAVE_VERSIONING libpam_la_LDFLAGS += -Wl,--version-script=$(srcdir)/libpam.map +diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h +index 33f87b90..c2578323 100644 +--- a/libpam/include/security/pam_modutil.h ++++ b/libpam/include/security/pam_modutil.h +@@ -147,7 +147,16 @@ pam_modutil_sanitize_helper_fds(pam_handle_t *pamh, + enum pam_modutil_redirect_fd redirect_stdout, + enum pam_modutil_redirect_fd redirect_stderr); + +-/* lookup a value for key in login.defs file or similar key value format */ ++/************************************************** ++ * @brief Lookup a value for the key in the file (i.e. login.defs or a similar ++ * key-value format file). ++ * ++ * @param[in] pamh The pam handle structure ++ * @param[in] file_name Configuration file name ++ * @param[in] key Lookup key ++ * ++ * @return value, or NULL if key was not found. ++ **************************************************/ + extern char * PAM_NONNULL((1,2,3)) + pam_modutil_search_key(pam_handle_t *pamh, + const char *file_name, +diff --git a/libpam/pam.pc.in b/libpam/pam.pc.in +index a7cf852d..c3fafe4b 100644 +--- a/libpam/pam.pc.in ++++ b/libpam/pam.pc.in +@@ -1,3 +1,5 @@ ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ + libdir=@libdir@ + includedir=@includedir@ + +diff --git a/libpam/pam_handlers.c b/libpam/pam_handlers.c +index ffa5e4ae..12ebb8fc 100644 +--- a/libpam/pam_handlers.c ++++ b/libpam/pam_handlers.c +@@ -889,8 +889,8 @@ int _pam_add_handler(pam_handle_t *pamh + handler_p = &((*handler_p)->next); + } + +- if ((*handler_p = malloc(sizeof(struct handler))) == NULL) { +- pam_syslog(pamh, LOG_CRIT, "cannot malloc struct handler #1"); ++ if ((*handler_p = calloc(1, sizeof(struct handler))) == NULL) { ++ pam_syslog(pamh, LOG_CRIT, "cannot allocate struct handler #1"); + return (PAM_ABORT); + } + +@@ -904,8 +904,6 @@ int _pam_add_handler(pam_handle_t *pamh + (*handler_p)->argv = argv; /* not a copy */ + if (((*handler_p)->mod_name = extract_modulename(mod_path)) == NULL) + return PAM_ABORT; +- (*handler_p)->grantor = 0; +- (*handler_p)->next = NULL; + + /* some of the modules have a second calling function */ + if (handler_p2) { +@@ -914,8 +912,8 @@ int _pam_add_handler(pam_handle_t *pamh + handler_p2 = &((*handler_p2)->next); + } + +- if ((*handler_p2 = malloc(sizeof(struct handler))) == NULL) { +- pam_syslog(pamh, LOG_CRIT, "cannot malloc struct handler #2"); ++ if ((*handler_p2 = calloc(1, sizeof(struct handler))) == NULL) { ++ pam_syslog(pamh, LOG_CRIT, "cannot allocate struct handler #2"); + return (PAM_ABORT); + } + +@@ -933,13 +931,9 @@ int _pam_add_handler(pam_handle_t *pamh + return (PAM_ABORT); + } + memcpy((*handler_p2)->argv, argv, argvlen); +- } else { +- (*handler_p2)->argv = NULL; /* no arguments */ + } + if (((*handler_p2)->mod_name = extract_modulename(mod_path)) == NULL) + return PAM_ABORT; +- (*handler_p2)->grantor = 0; +- (*handler_p2)->next = NULL; + } + + D(("_pam_add_handler: returning successfully")); +diff --git a/libpam_misc/pam_misc.pc.in b/libpam_misc/pam_misc.pc.in +index 0c8898cd..c3e03c4f 100644 +--- a/libpam_misc/pam_misc.pc.in ++++ b/libpam_misc/pam_misc.pc.in +@@ -1,3 +1,5 @@ ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ + libdir=@libdir@ + includedir=@includedir@ + +diff --git a/libpamc/pamc.pc.in b/libpamc/pamc.pc.in +index 25a63854..2d841ebb 100644 +--- a/libpamc/pamc.pc.in ++++ b/libpamc/pamc.pc.in +@@ -1,3 +1,5 @@ ++prefix=@prefix@ ++exec_prefix=@exec_prefix@ + libdir=@libdir@ + includedir=@includedir@ + diff --git a/modules/pam_access/Makefile.am b/modules/pam_access/Makefile.am index 5723dd59..b9fbefdb 100644 --- a/modules/pam_access/Makefile.am +++ b/modules/pam_access/Makefile.am @@ -18,8 +18,7 @@ securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_ACCESS_CONFIG=\"$(SCONFIGDIR)/access.conf\" \ - -DACCESS_CONF_GLOB=\"$(SCONFIGDIR)/access.d/*.conf\" $(WARN_CFLAGS) @@ -306,103 +594,2101 @@ index 5723dd59..b9fbefdb 100644 AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +diff --git a/modules/pam_access/pam_access.8.xml b/modules/pam_access/pam_access.8.xml +index 9a6556cc..db853410 100644 +--- a/modules/pam_access/pam_access.8.xml ++++ b/modules/pam_access/pam_access.8.xml +@@ -53,7 +53,7 @@ + or on terminal line names, X $DISPLAY values, + or PAM service names in case of non-networked logins. + +- ++ + By default rules for access management are taken from config file + /etc/security/access.conf if you don't specify + another file. +@@ -66,6 +66,26 @@ + If a config file is explicitly specified with the + option the files in the above directory are not parsed. + ++ ++ By default rules for access management are taken from config file ++ /etc/security/access.conf or, if that one is not ++ present, the file %vendordir%/security/access.conf. ++ These settings can be overruled by setting in a config file explicitly ++ specified with the option. ++ Then individual *.conf files from the ++ /etc/security/access.d/ and ++ %vendordir%/security/access.d directories are read. ++ If /etc/security/access.d/@filename@.conf exists, then ++ %vendordir%/security/access.d/@filename@.conf will not be used. ++ All access.d/*.conf files are sorted by their ++ @filename@.conf in lexicographic order regardless of which ++ of the directories they reside in. ++ The effect of the individual files is the same as if all the files were ++ concatenated together in the order of parsing. This means that once ++ a pattern is matched in some file no further files are parsed. ++ If a config file is explicitly specified with the ++ option the files in the above directories are not parsed. ++ + + If Linux PAM is compiled with audit support the module will report + when it denies access based on origin (host, tty, etc.). +@@ -233,6 +253,13 @@ + Default configuration file + + ++ ++ %vendordir%/security/access.conf ++ ++ Default configuration file if ++ /etc/security/access.conf does not exist. ++ ++ + + + diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c -index 277192b9..0d033aa2 100644 +index 277192b9..f7b47227 100644 --- a/modules/pam_access/pam_access.c +++ b/modules/pam_access/pam_access.c -@@ -56,6 +56,9 @@ +@@ -56,6 +56,13 @@ #include "pam_cc_compat.h" #include "pam_inline.h" - + +#define PAM_ACCESS_CONFIG (SCONFIGDIR "/access.conf") +#define ACCESS_CONF_GLOB (SCONFIGDIR "/access.d/*.conf") ++#ifdef VENDOR_SCONFIGDIR ++#define VENDOR_PAM_ACCESS_CONFIG (VENDOR_SCONFIGDIR "/access.conf") ++#define VENDOR_ACCESS_CONF_GLOB (VENDOR_SCONFIGDIR "/access.d/*.conf") ++#endif + /* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */ - + /* +@@ -151,6 +158,95 @@ parse_args(pam_handle_t *pamh, struct login_info *loginfo, + return 1; /* OK */ + } + ++/* --- evaluting all files in VENDORDIR/security/access.d and /etc/security/access.d --- */ ++static const char *base_name(const char *path) ++{ ++ const char *base = strrchr(path, '/'); ++ return base ? base+1 : path; ++} ++ ++static int ++compare_filename(const void *a, const void *b) ++{ ++ return strcmp(base_name(* (const char * const *) a), ++ base_name(* (const char * const *) b)); ++} ++ ++/* Evaluating a list of files which have to be parsed in the right order: ++ * ++ * - If etc/security/access.d/@filename@.conf exists, then ++ * %vendordir%/security/access.d/@filename@.conf should not be used. ++ * - All files in both access.d directories are sorted by their @filename@.conf in ++ * lexicographic order regardless of which of the directories they reside in. */ ++static char **read_access_dir(pam_handle_t *pamh) ++{ ++ glob_t globbuf; ++ size_t i=0; ++ int glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf); ++ char **file_list; ++ size_t file_list_size = glob_rv == 0 ? globbuf.gl_pathc : 0; ++ ++#ifdef VENDOR_ACCESS_CONF_GLOB ++ glob_t globbuf_vendor; ++ int glob_rv_vendor = glob(VENDOR_ACCESS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf_vendor); ++ if (glob_rv_vendor == 0) ++ file_list_size += globbuf_vendor.gl_pathc; ++#endif ++ file_list = malloc((file_list_size + 1) * sizeof(char*)); ++ if (file_list == NULL) { ++ pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for file list: %m"); ++#ifdef VENDOR_ACCESS_CONF_GLOB ++ if (glob_rv_vendor == 0) ++ globfree(&globbuf_vendor); ++#endif ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ return NULL; ++ } ++ ++ if (glob_rv == 0) { ++ for (i = 0; i < globbuf.gl_pathc; i++) { ++ file_list[i] = strdup(globbuf.gl_pathv[i]); ++ if (file_list[i] == NULL) { ++ pam_syslog(pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ } ++ } ++#ifdef VENDOR_ACCESS_CONF_GLOB ++ if (glob_rv_vendor == 0) { ++ for (size_t j = 0; j < globbuf_vendor.gl_pathc; j++) { ++ if (glob_rv == 0 && globbuf.gl_pathc > 0) { ++ int double_found = 0; ++ for (size_t k = 0; k < globbuf.gl_pathc; k++) { ++ if (strcmp(base_name(globbuf.gl_pathv[k]), ++ base_name(globbuf_vendor.gl_pathv[j])) == 0) { ++ double_found = 1; ++ break; ++ } ++ } ++ if (double_found) ++ continue; ++ } ++ file_list[i] = strdup(globbuf_vendor.gl_pathv[j]); ++ if (file_list[i] == NULL) { ++ pam_syslog(pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ i++; ++ } ++ globfree(&globbuf_vendor); ++ } ++#endif ++ file_list[i] = NULL; ++ qsort(file_list, i, sizeof(char *), compare_filename); ++ ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ ++ return file_list; ++} ++ + /* --- static functions for checking whether the user should be let in --- */ + + typedef int match_func (pam_handle_t *, char *, struct login_info *); +@@ -637,7 +733,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item) + if ((str_len = strlen(string)) > tok_len + && strcasecmp(tok, string + str_len - tok_len) == 0) + return YES; +- } else if (tok[tok_len - 1] == '.') { ++ } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */ + struct addrinfo hint; + + memset (&hint, '\0', sizeof (hint)); +@@ -678,7 +774,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item) + return NO; + } + +- /* Assume network/netmask with an IP of a host. */ ++ /* Assume network/netmask, IP address or hostname. */ + return network_netmask_match(pamh, tok, string, item); + } + +@@ -696,7 +792,7 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, + /* + * If the token has the magic value "ALL" the match always succeeds. + * Otherwise, return YES if the token fully matches the string. +- * "NONE" token matches NULL string. ++ * "NONE" token matches NULL string. + */ + + if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ +@@ -714,7 +810,8 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, + + /* network_netmask_match - match a string against one token + * where string is a hostname or ip (v4,v6) address and tok +- * represents either a single ip (v4,v6) address or a network/netmask ++ * represents either a hostname, a single ip (v4,v6) address ++ * or a network/netmask + */ + static int + network_netmask_match (pam_handle_t *pamh, +@@ -723,10 +820,12 @@ network_netmask_match (pam_handle_t *pamh, + char *netmask_ptr; + char netmask_string[MAXHOSTNAMELEN + 1]; + int addr_type; ++ struct addrinfo *ai = NULL; + + if (item->debug) +- pam_syslog (pamh, LOG_DEBUG, ++ pam_syslog (pamh, LOG_DEBUG, + "network_netmask_match: tok=%s, item=%s", tok, string); ++ + /* OK, check if tok is of type addr/mask */ + if ((netmask_ptr = strchr(tok, '/')) != NULL) + { +@@ -760,54 +859,108 @@ network_netmask_match (pam_handle_t *pamh, + netmask_ptr = number_to_netmask(netmask, addr_type, + netmask_string, MAXHOSTNAMELEN); + } +- } ++ ++ /* ++ * Construct an addrinfo list from the IP address. ++ * This should not fail as the input is a correct IP address... ++ */ ++ if (getaddrinfo (tok, NULL, NULL, &ai) != 0) ++ { ++ return NO; ++ } ++ } + else +- /* NO, then check if it is only an addr */ +- if (isipaddr(tok, NULL, NULL) != YES) ++ { ++ /* ++ * It is either an IP address or a hostname. ++ * Let getaddrinfo sort everything out ++ */ ++ if (getaddrinfo (tok, NULL, NULL, &ai) != 0) + { ++ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok); ++ + return NO; + } ++ netmask_ptr = NULL; ++ } + + if (isipaddr(string, NULL, NULL) != YES) + { +- /* Assume network/netmask with a name of a host. */ + struct addrinfo hint; + ++ /* Assume network/netmask with a name of a host. */ + memset (&hint, '\0', sizeof (hint)); + hint.ai_flags = AI_CANONNAME; + hint.ai_family = AF_UNSPEC; + + if (item->gai_rv != 0) ++ { ++ freeaddrinfo(ai); + return NO; ++ } + else if (!item->res && + (item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0) ++ { ++ freeaddrinfo(ai); + return NO; ++ } + else + { + struct addrinfo *runp = item->res; ++ struct addrinfo *runp1; + + while (runp != NULL) + { + char buf[INET6_ADDRSTRLEN]; + +- DIAG_PUSH_IGNORE_CAST_ALIGN; +- inet_ntop (runp->ai_family, +- runp->ai_family == AF_INET +- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr +- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, +- buf, sizeof (buf)); +- DIAG_POP_IGNORE_CAST_ALIGN; ++ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0) ++ { ++ freeaddrinfo(ai); ++ return NO; ++ } + +- if (are_addresses_equal(buf, tok, netmask_ptr)) ++ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next) + { +- return YES; ++ char buf1[INET6_ADDRSTRLEN]; ++ ++ if (runp->ai_family != runp1->ai_family) ++ continue; ++ ++ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0) ++ { ++ freeaddrinfo(ai); ++ return NO; ++ } ++ ++ if (are_addresses_equal (buf, buf1, netmask_ptr)) ++ { ++ freeaddrinfo(ai); ++ return YES; ++ } + } + runp = runp->ai_next; + } + } + } + else +- return (are_addresses_equal(string, tok, netmask_ptr)); ++ { ++ struct addrinfo *runp1; ++ ++ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next) ++ { ++ char buf1[INET6_ADDRSTRLEN]; ++ ++ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST); ++ ++ if (are_addresses_equal(string, buf1, netmask_ptr)) ++ { ++ freeaddrinfo(ai); ++ return YES; ++ } ++ } ++ } ++ ++ freeaddrinfo(ai); + + return NO; + } +@@ -828,7 +981,6 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, + char hostname[MAXHOSTNAMELEN + 1]; + int rv; + +- + /* set username */ + + if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS) { +@@ -853,6 +1005,18 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, + return PAM_ABORT; + } + ++#ifdef VENDOR_PAM_ACCESS_CONFIG ++ if (loginfo.config_file == default_config) { ++ /* Check whether PAM_ACCESS_CONFIG file is available. ++ * If it does not exist, fall back to VENDOR_PAM_ACCESS_CONFIG file. */ ++ struct stat buffer; ++ if (stat(loginfo.config_file, &buffer) != 0 && errno == ENOENT) { ++ default_config = VENDOR_PAM_ACCESS_CONFIG; ++ loginfo.config_file = default_config; ++ } ++ } ++#endif ++ + /* remote host name */ + + if (pam_get_item(pamh, PAM_RHOST, &void_from) +@@ -916,23 +1080,18 @@ pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, + rv = login_access(pamh, &loginfo); + + if (rv == NOMATCH && loginfo.config_file == default_config) { +- glob_t globbuf; +- int i, glob_rv; +- +- /* We do not manipulate locale as setlocale() is not +- * thread safe. We could use uselocale() in future. +- */ +- glob_rv = glob(ACCESS_CONF_GLOB, GLOB_ERR, NULL, &globbuf); +- if (!glob_rv) { +- /* Parse the *.conf files. */ +- for (i = 0; globbuf.gl_pathv[i] != NULL; i++) { +- loginfo.config_file = globbuf.gl_pathv[i]; +- rv = login_access(pamh, &loginfo); +- if (rv != NOMATCH) +- break; +- } +- globfree(&globbuf); +- } ++ char **filename_list = read_access_dir(pamh); ++ if (filename_list != NULL) { ++ for (int i = 0; filename_list[i] != NULL; i++) { ++ loginfo.config_file = filename_list[i]; ++ rv = login_access(pamh, &loginfo); ++ if (rv != NOMATCH) ++ break; ++ } ++ for (int i = 0; filename_list[i] != NULL; i++) ++ free(filename_list[i]); ++ free(filename_list); ++ } + } + + if (loginfo.gai_rv == 0 && loginfo.res) diff --git a/modules/pam_env/Makefile.am b/modules/pam_env/Makefile.am -index c66112d6..beca8e1a 100644 +index c66112d6..02cd9d37 100644 --- a/modules/pam_env/Makefile.am +++ b/modules/pam_env/Makefile.am -@@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR) +@@ -12,13 +12,13 @@ dist_man_MANS = pam_env.conf.5 pam_env.8 environment.5 + endif + XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml + dist_check_SCRIPTS = tst-pam_env +-TESTS = $(dist_check_SCRIPTS) ++TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) + + securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DDEFAULT_CONF_FILE=\"$(SCONFIGDIR)/pam_env.conf\" $(WARN_CFLAGS) + $(WARN_CFLAGS) AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +@@ -27,6 +27,9 @@ endif + securelib_LTLIBRARIES = pam_env.la + pam_env_la_LIBADD = $(top_builddir)/libpam/libpam.la + ++check_PROGRAMS = tst-pam_env-retval ++tst_pam_env_retval_LDADD = $(top_builddir)/libpam/libpam.la ++ + dist_secureconf_DATA = pam_env.conf + dist_sysconf_DATA = environment + diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c -index f5f8cead..c03ec3a3 100644 +index f5f8cead..66fbe240 100644 --- a/modules/pam_env/pam_env.c +++ b/modules/pam_env/pam_env.c @@ -41,6 +41,8 @@ typedef struct var { char *override; } VAR; - + +#define DEFAULT_CONF_FILE (SCONFIGDIR "/pam_env.conf") + #define BUF_SIZE 8192 #define MAX_ENV 8192 - + +@@ -51,15 +53,6 @@ typedef struct var { + #define UNDEFINE_VAR 102 + #define ILLEGAL_VAR 103 + +-static int _assemble_line(FILE *, char *, int); +-static int _parse_line(const pam_handle_t *, const char *, VAR *); +-static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */ +-static void _clean_var(VAR *); +-static int _expand_arg(pam_handle_t *, char **); +-static const char * _pam_get_item_byname(pam_handle_t *, const char *); +-static int _define_var(pam_handle_t *, int, VAR *); +-static int _undefine_var(pam_handle_t *, int, VAR *); +- + /* This is a special value used to designate an empty string */ + static char quote='\0'; + +@@ -126,166 +119,12 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, + return ctrl; + } + +-static int +-_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) +-{ +- int retval; +- char buffer[BUF_SIZE]; +- FILE *conf; +- VAR Var, *var=&Var; +- +- D(("Called.")); +- +- var->name=NULL; var->defval=NULL; var->override=NULL; +- +- D(("Config file name is: %s", file)); +- +- /* +- * Lets try to open the config file, parse it and process +- * any variables found. +- */ +- +- if ((conf = fopen(file,"r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file); +- return PAM_IGNORE; +- } +- +- /* _pam_assemble_line will provide a complete line from the config file, +- * with all comments removed and any escaped newlines fixed up +- */ +- +- while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { +- D(("Read line: %s", buffer)); +- +- if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) { +- retval = _check_var(pamh, var); +- +- if (DEFINE_VAR == retval) { +- retval = _define_var(pamh, ctrl, var); +- +- } else if (UNDEFINE_VAR == retval) { +- retval = _undefine_var(pamh, ctrl, var); +- } +- } +- if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval +- && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; +- +- _clean_var(var); +- +- } /* while */ +- +- (void) fclose(conf); +- +- /* tidy up */ +- _clean_var(var); /* We could have got here prematurely, +- * this is safe though */ +- D(("Exit.")); +- return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); +-} +- +-static int +-_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) +-{ +- int retval=PAM_SUCCESS, i, t; +- char buffer[BUF_SIZE], *key, *mark; +- FILE *conf; +- +- D(("Env file name is: %s", file)); +- +- if ((conf = fopen(file,"r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file); +- return PAM_IGNORE; +- } +- +- while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { +- D(("Read line: %s", buffer)); +- key = buffer; +- +- /* skip leading white space */ +- key += strspn(key, " \n\t"); +- +- /* skip blanks lines and comments */ +- if (key[0] == '#') +- continue; +- +- /* skip over "export " if present so we can be compat with +- bash type declarations */ +- if (strncmp(key, "export ", (size_t) 7) == 0) +- key += 7; +- +- /* now find the end of value */ +- mark = key; +- while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') +- mark++; +- if (mark[0] != '\0') +- mark[0] = '\0'; +- +- /* +- * sanity check, the key must be alphanumeric +- */ +- +- if (key[0] == '=') { +- pam_syslog(pamh, LOG_ERR, +- "missing key name '%s' in %s', ignoring", +- key, file); +- continue; +- } +- +- for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) +- if (!isalnum(key[i]) && key[i] != '_') { +- pam_syslog(pamh, LOG_ERR, +- "non-alphanumeric key '%s' in %s', ignoring", +- key, file); +- break; +- } +- /* non-alphanumeric key, ignore this line */ +- if (key[i] != '=' && key[i] != '\0') +- continue; +- +- /* now we try to be smart about quotes around the value, +- but not too smart, we can't get all fancy with escaped +- values like bash */ +- if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { +- for ( t = i+1 ; key[t] != '\0' ; t++) +- if (key[t] != '\"' && key[t] != '\'') +- key[i++] = key[t]; +- else if (key[t+1] != '\0') +- key[i++] = key[t]; +- key[i] = '\0'; +- } +- +- /* if this is a request to delete a variable, check that it's +- actually set first, so we don't get a vague error back from +- pam_putenv() */ +- for (i = 0; key[i] != '=' && key[i] != '\0'; i++); +- +- if (key[i] == '\0' && !pam_getenv(pamh,key)) +- continue; +- +- /* set the env var, if it fails, we break out of the loop */ +- retval = pam_putenv(pamh, key); +- if (retval != PAM_SUCCESS) { +- D(("error setting env \"%s\"", key)); +- break; +- } else if (ctrl & PAM_DEBUG_ARG) { +- pam_syslog(pamh, LOG_DEBUG, +- "pam_putenv(\"%s\")", key); +- } +- } +- +- (void) fclose(conf); +- +- /* tidy up */ +- D(("Exit.")); +- return retval; +-} +- + /* + * This is where we read a line of the PAM config file. The line may be + * preceded by lines of comments and also extended with "\\\n" + */ +- +-static int _assemble_line(FILE *f, char *buffer, int buf_len) ++static int ++_assemble_line(FILE *f, char *buffer, int buf_len) + { + char *p = buffer; + char *s, *os; +@@ -374,7 +213,7 @@ static int _assemble_line(FILE *f, char *buffer, int buf_len) + } + + static int +-_parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var) ++_parse_line(const pam_handle_t *pamh, const char *buffer, VAR *var) + { + /* + * parse buffer into var, legal syntax is +@@ -469,75 +308,57 @@ _parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var) + return GOOD_LINE; + } + +-static int _check_var(pam_handle_t *pamh, VAR *var) ++static const char * ++_pam_get_item_byname(pam_handle_t *pamh, const char *name) + { + /* +- * Examine the variable and determine what action to take. +- * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take +- * or a PAM_* error code if passed back from other routines +- * +- * if no DEFAULT provided, the empty string is assumed +- * if no OVERRIDE provided, the empty string is assumed +- * if DEFAULT= and OVERRIDE evaluates to the empty string, +- * this variable should be undefined +- * if DEFAULT="" and OVERRIDE evaluates to the empty string, +- * this variable should be defined with no value +- * if OVERRIDE=value and value turns into the empty string, DEFAULT is used +- * +- * If DEFINE_VAR is to be returned, the correct value to define will +- * be pointed to by var->value ++ * This function just allows me to use names as given in the config ++ * file and translate them into the appropriate PAM_ITEM macro + */ + +- int retval; ++ int item; ++ const void *itemval; + + D(("Called.")); +- +- /* +- * First thing to do is to expand any arguments, but only +- * if they are not the special quote values (cause expand_arg +- * changes memory). +- */ +- +- if (var->defval && ("e != var->defval) && +- ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { +- return retval; +- } +- if (var->override && ("e != var->override) && +- ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { +- return retval; ++ if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) { ++ item = PAM_USER; ++ } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { ++ item = PAM_USER_PROMPT; ++ } else if (strcmp(name, "PAM_TTY") == 0) { ++ item = PAM_TTY; ++ } else if (strcmp(name, "PAM_RUSER") == 0) { ++ item = PAM_RUSER; ++ } else if (strcmp(name, "PAM_RHOST") == 0) { ++ item = PAM_RHOST; ++ } else { ++ D(("Unknown PAM_ITEM: <%s>", name)); ++ pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name); ++ return NULL; + } + +- /* Now its easy */ +- +- if (var->override && *(var->override)) { +- /* if there is a non-empty string in var->override, we use it */ +- D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); +- var->value = var->override; +- retval = DEFINE_VAR; +- } else { ++ if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) { ++ D(("pam_get_item failed")); ++ return NULL; /* let pam_get_item() log the error */ ++ } + +- var->value = var->defval; +- if ("e == var->defval) { +- /* +- * This means that the empty string was given for defval value +- * which indicates that a variable should be defined with no value +- */ +- D(("An empty variable: <%s>", var->name)); +- retval = DEFINE_VAR; +- } else if (var->defval) { +- D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); +- retval = DEFINE_VAR; +- } else { +- D(("UNDEFINE variable <%s>", var->name)); +- retval = UNDEFINE_VAR; ++ if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) { ++ struct passwd *user_entry; ++ user_entry = pam_modutil_getpwnam (pamh, itemval); ++ if (!user_entry) { ++ pam_syslog(pamh, LOG_ERR, "No such user!?"); ++ return NULL; + } ++ return (strcmp(name, "SHELL") == 0) ? ++ user_entry->pw_shell : ++ user_entry->pw_dir; + } + + D(("Exit.")); +- return retval; ++ return itemval; + } + +-static int _expand_arg(pam_handle_t *pamh, char **value) ++static int ++_expand_arg(pam_handle_t *pamh, char **value) + { + const char *orig=*value, *tmpptr=NULL; + char *ptr; /* +@@ -677,55 +498,96 @@ static int _expand_arg(pam_handle_t *pamh, char **value) + return PAM_SUCCESS; + } + +-static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name) ++static int ++_check_var(pam_handle_t *pamh, VAR *var) + { + /* +- * This function just allows me to use names as given in the config +- * file and translate them into the appropriate PAM_ITEM macro ++ * Examine the variable and determine what action to take. ++ * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take ++ * or a PAM_* error code if passed back from other routines ++ * ++ * if no DEFAULT provided, the empty string is assumed ++ * if no OVERRIDE provided, the empty string is assumed ++ * if DEFAULT= and OVERRIDE evaluates to the empty string, ++ * this variable should be undefined ++ * if DEFAULT="" and OVERRIDE evaluates to the empty string, ++ * this variable should be defined with no value ++ * if OVERRIDE=value and value turns into the empty string, DEFAULT is used ++ * ++ * If DEFINE_VAR is to be returned, the correct value to define will ++ * be pointed to by var->value + */ + +- int item; +- const void *itemval; ++ int retval; + + D(("Called.")); +- if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) { +- item = PAM_USER; +- } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { +- item = PAM_USER_PROMPT; +- } else if (strcmp(name, "PAM_TTY") == 0) { +- item = PAM_TTY; +- } else if (strcmp(name, "PAM_RUSER") == 0) { +- item = PAM_RUSER; +- } else if (strcmp(name, "PAM_RHOST") == 0) { +- item = PAM_RHOST; +- } else { +- D(("Unknown PAM_ITEM: <%s>", name)); +- pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name); +- return NULL; +- } + +- if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) { +- D(("pam_get_item failed")); +- return NULL; /* let pam_get_item() log the error */ ++ /* ++ * First thing to do is to expand any arguments, but only ++ * if they are not the special quote values (cause expand_arg ++ * changes memory). ++ */ ++ ++ if (var->defval && ("e != var->defval) && ++ ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { ++ return retval; ++ } ++ if (var->override && ("e != var->override) && ++ ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { ++ return retval; + } + +- if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) { +- struct passwd *user_entry; +- user_entry = pam_modutil_getpwnam (pamh, itemval); +- if (!user_entry) { +- pam_syslog(pamh, LOG_ERR, "No such user!?"); +- return NULL; ++ /* Now its easy */ ++ ++ if (var->override && *(var->override)) { ++ /* if there is a non-empty string in var->override, we use it */ ++ D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); ++ var->value = var->override; ++ retval = DEFINE_VAR; ++ } else { ++ ++ var->value = var->defval; ++ if ("e == var->defval) { ++ /* ++ * This means that the empty string was given for defval value ++ * which indicates that a variable should be defined with no value ++ */ ++ D(("An empty variable: <%s>", var->name)); ++ retval = DEFINE_VAR; ++ } else if (var->defval) { ++ D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); ++ retval = DEFINE_VAR; ++ } else { ++ D(("UNDEFINE variable <%s>", var->name)); ++ retval = UNDEFINE_VAR; + } +- return (strcmp(name, "SHELL") == 0) ? +- user_entry->pw_shell : +- user_entry->pw_dir; + } + + D(("Exit.")); +- return itemval; ++ return retval; ++} ++ ++static void ++_clean_var(VAR *var) ++{ ++ if (var->name) { ++ free(var->name); ++ } ++ if (var->defval && ("e != var->defval)) { ++ free(var->defval); ++ } ++ if (var->override && ("e != var->override)) { ++ free(var->override); ++ } ++ var->name = NULL; ++ var->value = NULL; /* never has memory specific to it */ ++ var->defval = NULL; ++ var->override = NULL; ++ return; + } + +-static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var) ++static int ++_define_var(pam_handle_t *pamh, int ctrl, VAR *var) + { + /* We have a variable to define, this is a simple function */ + +@@ -747,7 +609,8 @@ static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var) + return retval; + } + +-static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var) ++static int ++_undefine_var(pam_handle_t *pamh, int ctrl, VAR *var) + { + /* We have a variable to undefine, this is a simple function */ + +@@ -758,25 +621,159 @@ static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var) + return pam_putenv(pamh, var->name); + } + +-static void _clean_var(VAR *var) ++static int ++_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) + { +- if (var->name) { +- free(var->name); ++ int retval; ++ char buffer[BUF_SIZE]; ++ FILE *conf; ++ VAR Var, *var=&Var; ++ ++ D(("Called.")); ++ ++ var->name=NULL; var->defval=NULL; var->override=NULL; ++ ++ D(("Config file name is: %s", file)); ++ ++ /* ++ * Lets try to open the config file, parse it and process ++ * any variables found. ++ */ ++ ++ if ((conf = fopen(file,"r")) == NULL) { ++ pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file); ++ return PAM_IGNORE; + } +- if (var->defval && ("e != var->defval)) { +- free(var->defval); ++ ++ /* _pam_assemble_line will provide a complete line from the config file, ++ * with all comments removed and any escaped newlines fixed up ++ */ ++ ++ while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { ++ D(("Read line: %s", buffer)); ++ ++ if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) { ++ retval = _check_var(pamh, var); ++ ++ if (DEFINE_VAR == retval) { ++ retval = _define_var(pamh, ctrl, var); ++ ++ } else if (UNDEFINE_VAR == retval) { ++ retval = _undefine_var(pamh, ctrl, var); ++ } ++ } ++ if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval ++ && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; ++ ++ _clean_var(var); ++ ++ } /* while */ ++ ++ (void) fclose(conf); ++ ++ /* tidy up */ ++ _clean_var(var); /* We could have got here prematurely, ++ * this is safe though */ ++ D(("Exit.")); ++ return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); ++} ++ ++static int ++_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) ++{ ++ int retval=PAM_SUCCESS, i, t; ++ char buffer[BUF_SIZE], *key, *mark; ++ FILE *conf; ++ ++ D(("Env file name is: %s", file)); ++ ++ if ((conf = fopen(file,"r")) == NULL) { ++ pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file); ++ return PAM_IGNORE; + } +- if (var->override && ("e != var->override)) { +- free(var->override); ++ ++ while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { ++ D(("Read line: %s", buffer)); ++ key = buffer; ++ ++ /* skip leading white space */ ++ key += strspn(key, " \n\t"); ++ ++ /* skip blanks lines and comments */ ++ if (key[0] == '#') ++ continue; ++ ++ /* skip over "export " if present so we can be compat with ++ bash type declarations */ ++ if (strncmp(key, "export ", (size_t) 7) == 0) ++ key += 7; ++ ++ /* now find the end of value */ ++ mark = key; ++ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') ++ mark++; ++ if (mark[0] != '\0') ++ mark[0] = '\0'; ++ ++ /* ++ * sanity check, the key must be alphanumeric ++ */ ++ ++ if (key[0] == '=') { ++ pam_syslog(pamh, LOG_ERR, ++ "missing key name '%s' in %s', ignoring", ++ key, file); ++ continue; ++ } ++ ++ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) ++ if (!isalnum(key[i]) && key[i] != '_') { ++ pam_syslog(pamh, LOG_ERR, ++ "non-alphanumeric key '%s' in %s', ignoring", ++ key, file); ++ break; ++ } ++ /* non-alphanumeric key, ignore this line */ ++ if (key[i] != '=' && key[i] != '\0') ++ continue; ++ ++ /* now we try to be smart about quotes around the value, ++ but not too smart, we can't get all fancy with escaped ++ values like bash */ ++ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { ++ for ( t = i+1 ; key[t] != '\0' ; t++) ++ if (key[t] != '\"' && key[t] != '\'') ++ key[i++] = key[t]; ++ else if (key[t+1] != '\0') ++ key[i++] = key[t]; ++ key[i] = '\0'; ++ } ++ ++ /* if this is a request to delete a variable, check that it's ++ actually set first, so we don't get a vague error back from ++ pam_putenv() */ ++ for (i = 0; key[i] != '=' && key[i] != '\0'; i++); ++ ++ if (key[i] == '\0' && !pam_getenv(pamh,key)) ++ continue; ++ ++ /* set the env var, if it fails, we break out of the loop */ ++ retval = pam_putenv(pamh, key); ++ if (retval != PAM_SUCCESS) { ++ D(("error setting env \"%s\"", key)); ++ break; ++ } else if (ctrl & PAM_DEBUG_ARG) { ++ pam_syslog(pamh, LOG_DEBUG, ++ "pam_putenv(\"%s\")", key); ++ } + } +- var->name = NULL; +- var->value = NULL; /* never has memory specific to it */ +- var->defval = NULL; +- var->override = NULL; +- return; +-} + ++ (void) fclose(conf); + ++ /* tidy up */ ++ D(("Exit.")); ++ return retval; ++} + + /* --- authentication management functions (only) --- */ + +diff --git a/modules/pam_env/tst-pam_env-retval.c b/modules/pam_env/tst-pam_env-retval.c +new file mode 100644 +index 00000000..6b9b3065 +--- /dev/null ++++ b/modules/pam_env/tst-pam_env-retval.c +@@ -0,0 +1,199 @@ ++/* ++ * Check pam_env return values. ++ * ++ * Copyright (c) 2020-2022 Dmitry V. Levin ++ * Copyright (c) 2022 Stefan Schubert ++ */ ++ ++#include "test_assert.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#define MODULE_NAME "pam_env" ++#define TEST_NAME "tst-" MODULE_NAME "-retval" ++ ++static const char service_file[] = TEST_NAME ".service"; ++static const char missing_file[] = TEST_NAME ".missing"; ++static const char my_conf[] = TEST_NAME ".conf"; ++static const char my_env[] = TEST_NAME ".env"; ++ ++static struct pam_conv conv; ++ ++static void ++setup(void) ++{ ++ FILE *fp; ++ ++ ASSERT_NE(NULL, fp = fopen(my_conf, "w")); ++ ASSERT_LT(0, fprintf(fp, ++ "EDITOR\tDEFAULT=vim\n" ++ "PAGER\tDEFAULT=more\n")); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_NE(NULL, fp = fopen(my_env, "w")); ++ ASSERT_LT(0, fprintf(fp, ++ "test_value=foo\n" ++ "test2_value=bar\n")); ++ ASSERT_EQ(0, fclose(fp)); ++} ++ ++static void ++cleanup(void) ++{ ++ ASSERT_EQ(0, unlink(my_conf)); ++ ASSERT_EQ(0, unlink(my_env)); ++} ++ ++static void ++check_array(const char **array1, char **array2) ++{ ++ for (const char **a1 = array1; *a1 != NULL; ++a1) { ++ char **a2; ++ for (a2 = array2; *a2 != NULL; ++a2) { ++ if (strcmp(*a1, *a2) == 0) ++ break; ++ } ++ ASSERT_NE(NULL, *a2); ++ } ++} ++ ++static void ++check_env(const char **list) ++{ ++ pam_handle_t *pamh = NULL; ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ++ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0)); ++ ++ char **env_list = pam_getenvlist(pamh); ++ ASSERT_NE(NULL, env_list); ++ ++ check_array(list, env_list); ++ ++ for (char **e = env_list; *e != NULL; ++e) ++ free(*e); ++ free(env_list); ++ ++ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++} ++ ++int ++main(void) ++{ ++ pam_handle_t *pamh = NULL; ++ FILE *fp; ++ char cwd[PATH_MAX]; ++ ++ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd))); ++ ++ setup(); ++ ++ /* ++ * When conffile= specifies a missing file, all methods except ++ * pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE. ++ * The return code of the stack where every module returns PAM_IGNORE ++ * is PAM_PERM_DENIED. ++ */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "auth required %s/.libs/%s.so conffile=%s/%s\n" ++ "account required %s/.libs/%s.so conffile=%s/%s\n" ++ "password required %s/.libs/%s.so conffile=%s/%s\n" ++ "session required %s/.libs/%s.so conffile=%s/%s\n", ++ cwd, MODULE_NAME, cwd, missing_file, ++ cwd, MODULE_NAME, cwd, missing_file, ++ cwd, MODULE_NAME, cwd, missing_file, ++ cwd, MODULE_NAME, cwd, missing_file)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0)); ++ ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0)); ++ ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0)); ++ ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0)); ++ ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, 0)); ++ ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++ pamh = NULL; ++ ++ /* ++ * When conffile= specifies a missing file, all methods except ++ * pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE. ++ * pam_permit is added after pam_env to convert PAM_IGNORE to PAM_SUCCESS. ++ */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "auth required %s/.libs/%s.so conffile=%s/%s\n" ++ "auth required %s/../pam_permit/.libs/pam_permit.so\n" ++ "account required %s/.libs/%s.so conffile=%s/%s\n" ++ "account required %s/../pam_permit/.libs/pam_permit.so\n" ++ "password required %s/.libs/%s.so conffile=%s/%s\n" ++ "password required %s/../pam_permit/.libs/pam_permit.so\n" ++ "session required %s/.libs/%s.so conffile=%s/%s\n" ++ "session required %s/../pam_permit/.libs/pam_permit.so\n", ++ cwd, MODULE_NAME, cwd, missing_file, cwd, ++ cwd, MODULE_NAME, cwd, missing_file, cwd, ++ cwd, MODULE_NAME, cwd, missing_file, cwd, ++ cwd, MODULE_NAME, cwd, missing_file, cwd)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0)); ++ ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0)); ++ ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++ pamh = NULL; ++ ++ /* ++ * conffile= specifies an existing file, ++ * envfile= specifies an empty file. ++ */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "session required %s/.libs/%s.so" ++ " conffile=%s/%s envfile=%s\n", ++ cwd, MODULE_NAME, ++ cwd, my_conf, "/dev/null")); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ const char *env1[] = { "EDITOR=vim", "PAGER=more", NULL }; ++ check_env(env1); ++ ++ /* ++ * conffile= specifies an empty file, ++ * envfile= specifies an existing file. ++ */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "session required %s/.libs/%s.so" ++ " conffile=%s envfile=%s/%s\n", ++ cwd, MODULE_NAME, ++ "/dev/null", cwd, my_env)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ const char *env2[] = { "test_value=foo", "test2_value=bar", NULL }; ++ check_env(env2); ++ ++ /* cleanup */ ++ cleanup(); ++ ASSERT_EQ(0, unlink(service_file)); ++ ++ return 0; ++} +diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c +index 05dec167..aeb98cdc 100644 +--- a/modules/pam_exec/pam_exec.c ++++ b/modules/pam_exec/pam_exec.c +@@ -48,6 +48,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -105,6 +106,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + FILE *stdout_file = NULL; + int retval; + const char *name; ++ struct sigaction newsa, oldsa; + + if (argc < 1) { + pam_syslog (pamh, LOG_ERR, +@@ -226,6 +228,13 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + return PAM_SERVICE_ERR; + } + ++ memset(&newsa, '\0', sizeof(newsa)); ++ newsa.sa_handler = SIG_DFL; ++ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { ++ pam_syslog(pamh, LOG_ERR, "failed to reset SIGCHLD handler: %m"); ++ return PAM_SYSTEM_ERR; ++ } ++ + pid = fork(); + if (pid == -1) + return PAM_SYSTEM_ERR; +@@ -263,6 +272,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + + while ((rc = waitpid (pid, &status, 0)) == -1 && + errno == EINTR); ++ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ + if (rc == (pid_t)-1) + { + pam_syslog (pamh, LOG_ERR, "waitpid returns with -1: %m"); +@@ -305,9 +315,9 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + } + else /* child */ + { +- char **arggv; ++ const char **arggv; + int i; +- char **envlist, **tmp; ++ char **envlist; + int envlen, nitems; + char *envstr; + enum pam_modutil_redirect_fd redirect_stdin = +@@ -418,7 +428,7 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + _exit (ENOMEM); + + for (i = 0; i < (argc - optargc); i++) +- arggv[i] = strdup(argv[i+optargc]); ++ arggv[i] = argv[i+optargc]; + arggv[i] = NULL; + + /* +@@ -430,14 +440,12 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + /* nothing */ ; + nitems = PAM_ARRAY_SIZE(env_items); + /* + 2 because of PAM_TYPE and NULL entry */ +- tmp = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist)); +- if (tmp == NULL) ++ envlist = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist)); ++ if (envlist == NULL) + { +- free(envlist); + pam_syslog (pamh, LOG_CRIT, "realloc environment failed: %m"); + _exit (ENOMEM); + } +- envlist = tmp; + for (i = 0; i < nitems; ++i) + { + const void *item; +@@ -446,7 +454,6 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + continue; + if (asprintf(&envstr, "%s=%s", env_items[i].name, (const char *)item) < 0) + { +- free(envlist); + pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m"); + _exit (ENOMEM); + } +@@ -456,7 +463,6 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + + if (asprintf(&envstr, "PAM_TYPE=%s", pam_type) < 0) + { +- free(envlist); + pam_syslog (pamh, LOG_CRIT, "prepare environment failed: %m"); + _exit (ENOMEM); + } +@@ -466,10 +472,11 @@ call_exec (const char *pam_type, pam_handle_t *pamh, + if (debug) + pam_syslog (pamh, LOG_DEBUG, "Calling %s ...", arggv[0]); + +- execve (arggv[0], arggv, envlist); ++ DIAG_PUSH_IGNORE_CAST_QUAL; ++ execve (arggv[0], (char **) arggv, envlist); ++ DIAG_POP_IGNORE_CAST_QUAL; + i = errno; + pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", arggv[0]); +- free(envlist); + _exit (i); + } + return PAM_SYSTEM_ERR; /* will never be reached. */ diff --git a/modules/pam_faillock/Makefile.am b/modules/pam_faillock/Makefile.am -index 44a49660..16d9f8bc 100644 +index 44a49660..ca73bd05 100644 --- a/modules/pam_faillock/Makefile.am +++ b/modules/pam_faillock/Makefile.am -@@ -15,7 +15,7 @@ endif +@@ -15,12 +15,12 @@ endif XMLS = README.xml pam_faillock.8.xml faillock.8.xml faillock.conf.5.xml - + dist_check_SCRIPTS = tst-pam_faillock -TESTS = $(dist_check_SCRIPTS) +TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) - + securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) + +-noinst_HEADERS = faillock.h ++noinst_HEADERS = faillock.h faillock_config.h + + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ + $(WARN_CFLAGS) @@ -33,6 +33,9 @@ if HAVE_VERSIONING pam_faillock_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map endif - + +check_PROGRAMS = tst-pam_faillock-retval +tst_pam_faillock_retval_LDADD = $(top_builddir)/libpam/libpam.la + faillock_LDFLAGS = @EXE_LDFLAGS@ faillock_LDADD = $(top_builddir)/libpam/libpam.la $(LIBAUDIT) - + +@@ -41,8 +44,8 @@ dist_secureconf_DATA = faillock.conf + securelib_LTLIBRARIES = pam_faillock.la + sbin_PROGRAMS = faillock + +-pam_faillock_la_SOURCES = pam_faillock.c faillock.c +-faillock_SOURCES = main.c faillock.c ++pam_faillock_la_SOURCES = pam_faillock.c faillock.c faillock_config.c ++faillock_SOURCES = main.c faillock.c faillock_config.c + + if ENABLE_REGENERATE_MAN + dist_noinst_DATA = README +diff --git a/modules/pam_faillock/faillock.8.xml b/modules/pam_faillock/faillock.8.xml +index 6c20593c..81d2107c 100644 +--- a/modules/pam_faillock/faillock.8.xml ++++ b/modules/pam_faillock/faillock.8.xml +@@ -55,14 +55,31 @@ + + OPTIONS + ++ ++ ++ ++ ++ ++ ++ The file where the configuration is located. The default is ++ /etc/security/faillock.conf. ++ ++ ++ + + + + + + +- The directory where the user files with the failure records are kept. The +- default is /var/run/faillock. ++ The directory where the user files with the failure records are kept. ++ ++ ++ The priority to set this option is to use the value provided ++ from the command line. If this isn't provided, then the value ++ from the configuration file is used. Finally, if neither of ++ them has been provided, then ++ /var/run/faillock is used. + + + +diff --git a/modules/pam_faillock/faillock.conf.5.xml b/modules/pam_faillock/faillock.conf.5.xml +index 04a84107..8faa5915 100644 +--- a/modules/pam_faillock/faillock.conf.5.xml ++++ b/modules/pam_faillock/faillock.conf.5.xml +@@ -44,6 +44,10 @@ + The directory where the user files with the failure records are kept. The + default is /var/run/faillock. + ++ ++ Note: These files will disappear after reboot on systems configured with ++ directory /var/run/faillock mounted on virtual memory. ++ + + + diff --git a/modules/pam_faillock/faillock.h b/modules/pam_faillock/faillock.h -index b22a9dfb..c3f157ef 100644 +index b22a9dfb..0ea0ffba 100644 --- a/modules/pam_faillock/faillock.h +++ b/modules/pam_faillock/faillock.h -@@ -67,7 +67,10 @@ struct tally_data { +@@ -67,7 +67,6 @@ struct tally_data { }; - + #define FAILLOCK_DEFAULT_TALLYDIR "/var/run/faillock" -#define FAILLOCK_DEFAULT_CONF "/etc/security/faillock.conf" + + int open_tally(const char *dir, const char *user, uid_t uid, int create); + int read_tally(int fd, struct tally_data *tallies); +diff --git a/modules/pam_faillock/faillock_config.c b/modules/pam_faillock/faillock_config.c +new file mode 100644 +index 00000000..0d14aad1 +--- /dev/null ++++ b/modules/pam_faillock/faillock_config.c +@@ -0,0 +1,266 @@ ++/* ++ * Copyright (c) 2022 Tomas Mraz ++ * Copyright (c) 2022 Iker Pedrosa ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * the GNU Public License, in which case the provisions of the GPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the GPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "faillock_config.h" ++#include "faillock.h" ++ +#define FAILLOCK_DEFAULT_CONF SCONFIGDIR "/faillock.conf" +#ifdef VENDOR_SCONFIGDIR +#define VENDOR_FAILLOCK_DEFAULT_CONF VENDOR_SCONFIGDIR "/faillock.conf" +#endif - - int open_tally(const char *dir, const char *user, uid_t uid, int create); - int read_tally(int fd, struct tally_data *tallies); ++ ++static void PAM_FORMAT((printf, 3, 4)) PAM_NONNULL((3)) ++config_log(const pam_handle_t *pamh, int priority, const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ if (pamh) { ++ pam_vsyslog(pamh, priority, fmt, args); ++ } else { ++ char *buf = NULL; ++ ++ if (vasprintf(&buf, fmt, args) < 0) { ++ fprintf(stderr, "vasprintf: %m"); ++ va_end(args); ++ return; ++ } ++ fprintf(stderr, "%s\n", buf); ++ free(buf); ++ } ++ va_end(args); ++} ++ ++/* parse a single configuration file */ ++int ++read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile) ++{ ++ char linebuf[FAILLOCK_CONF_MAX_LINELEN+1]; ++ const char *fname = (cfgfile != NULL) ? cfgfile : FAILLOCK_DEFAULT_CONF; ++ FILE *f = fopen(fname, "r"); ++ ++#ifdef VENDOR_FAILLOCK_DEFAULT_CONF ++ if (f == NULL && errno == ENOENT && cfgfile == NULL) { ++ /* ++ * If the default configuration file in /etc does not exist, ++ * try the vendor configuration file as fallback. ++ */ ++ f = fopen(VENDOR_FAILLOCK_DEFAULT_CONF, "r"); ++ } ++#endif /* VENDOR_FAILLOCK_DEFAULT_CONF */ ++ ++ if (f == NULL) { ++ /* ignore non-existent default config file */ ++ if (errno == ENOENT && cfgfile == NULL) ++ return PAM_SUCCESS; ++ return PAM_SERVICE_ERR; ++ } ++ ++ while (fgets(linebuf, sizeof(linebuf), f) != NULL) { ++ size_t len; ++ char *ptr; ++ char *name; ++ int eq; ++ ++ len = strlen(linebuf); ++ /* len cannot be 0 unless there is a bug in fgets */ ++ if (len && linebuf[len - 1] != '\n' && !feof(f)) { ++ (void) fclose(f); ++ return PAM_SERVICE_ERR; ++ } ++ ++ if ((ptr=strchr(linebuf, '#')) != NULL) { ++ *ptr = '\0'; ++ } else { ++ ptr = linebuf + len; ++ } ++ ++ /* drop terminating whitespace including the \n */ ++ while (ptr > linebuf) { ++ if (!isspace(*(ptr-1))) { ++ *ptr = '\0'; ++ break; ++ } ++ --ptr; ++ } ++ ++ /* skip initial whitespace */ ++ for (ptr = linebuf; isspace(*ptr); ptr++); ++ if (*ptr == '\0') ++ continue; ++ ++ /* grab the key name */ ++ eq = 0; ++ name = ptr; ++ while (*ptr != '\0') { ++ if (isspace(*ptr) || *ptr == '=') { ++ eq = *ptr == '='; ++ *ptr = '\0'; ++ ++ptr; ++ break; ++ } ++ ++ptr; ++ } ++ ++ /* grab the key value */ ++ while (*ptr != '\0') { ++ if (*ptr != '=' || eq) { ++ if (!isspace(*ptr)) { ++ break; ++ } ++ } else { ++ eq = 1; ++ } ++ ++ptr; ++ } ++ ++ /* set the key:value pair on opts */ ++ set_conf_opt(pamh, opts, name, ptr); ++ } ++ ++ (void)fclose(f); ++ return PAM_SUCCESS; ++} ++ ++void ++set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, ++ const char *value) ++{ ++ if (strcmp(name, "dir") == 0) { ++ if (value[0] != '/') { ++ config_log(pamh, LOG_ERR, ++ "Tally directory is not absolute path (%s); keeping value", ++ value); ++ } else { ++ free(opts->dir); ++ opts->dir = strdup(value); ++ if (opts->dir == NULL) { ++ opts->fatal_error = 1; ++ config_log(pamh, LOG_CRIT, "Error allocating memory: %m"); ++ } ++ } ++ } ++ else if (strcmp(name, "deny") == 0) { ++ if (sscanf(value, "%hu", &opts->deny) != 1) { ++ config_log(pamh, LOG_ERR, ++ "Bad number supplied for deny argument"); ++ } ++ } ++ else if (strcmp(name, "fail_interval") == 0) { ++ unsigned int temp; ++ if (sscanf(value, "%u", &temp) != 1 || ++ temp > MAX_TIME_INTERVAL) { ++ config_log(pamh, LOG_ERR, ++ "Bad number supplied for fail_interval argument"); ++ } else { ++ opts->fail_interval = temp; ++ } ++ } ++ else if (strcmp(name, "unlock_time") == 0) { ++ unsigned int temp; ++ ++ if (strcmp(value, "never") == 0) { ++ opts->unlock_time = 0; ++ } ++ else if (sscanf(value, "%u", &temp) != 1 || ++ temp > MAX_TIME_INTERVAL) { ++ config_log(pamh, LOG_ERR, ++ "Bad number supplied for unlock_time argument"); ++ } ++ else { ++ opts->unlock_time = temp; ++ } ++ } ++ else if (strcmp(name, "root_unlock_time") == 0) { ++ unsigned int temp; ++ ++ if (strcmp(value, "never") == 0) { ++ opts->root_unlock_time = 0; ++ } ++ else if (sscanf(value, "%u", &temp) != 1 || ++ temp > MAX_TIME_INTERVAL) { ++ config_log(pamh, LOG_ERR, ++ "Bad number supplied for root_unlock_time argument"); ++ } else { ++ opts->root_unlock_time = temp; ++ } ++ } ++ else if (strcmp(name, "admin_group") == 0) { ++ free(opts->admin_group); ++ opts->admin_group = strdup(value); ++ if (opts->admin_group == NULL) { ++ opts->fatal_error = 1; ++ config_log(pamh, LOG_CRIT, "Error allocating memory: %m"); ++ } ++ } ++ else if (strcmp(name, "even_deny_root") == 0) { ++ opts->flags |= FAILLOCK_FLAG_DENY_ROOT; ++ } ++ else if (strcmp(name, "audit") == 0) { ++ opts->flags |= FAILLOCK_FLAG_AUDIT; ++ } ++ else if (strcmp(name, "silent") == 0) { ++ opts->flags |= FAILLOCK_FLAG_SILENT; ++ } ++ else if (strcmp(name, "no_log_info") == 0) { ++ opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO; ++ } ++ else if (strcmp(name, "local_users_only") == 0) { ++ opts->flags |= FAILLOCK_FLAG_LOCAL_ONLY; ++ } ++ else if (strcmp(name, "nodelay") == 0) { ++ opts->flags |= FAILLOCK_FLAG_NO_DELAY; ++ } ++ else { ++ config_log(pamh, LOG_ERR, "Unknown option: %s", name); ++ } ++} ++ ++const char *get_tally_dir(const struct options *opts) ++{ ++ return (opts->dir != NULL) ? opts->dir : FAILLOCK_DEFAULT_TALLYDIR; ++} +diff --git a/modules/pam_faillock/faillock_config.h b/modules/pam_faillock/faillock_config.h +new file mode 100644 +index 00000000..04bc699b +--- /dev/null ++++ b/modules/pam_faillock/faillock_config.h +@@ -0,0 +1,90 @@ ++/* ++ * Copyright (c) 2022 Tomas Mraz ++ * Copyright (c) 2022 Iker Pedrosa ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * the GNU Public License, in which case the provisions of the GPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the GPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++/* ++ * faillock_config.h - load configuration options from file ++ * ++ */ ++ ++#ifndef _FAILLOCK_CONFIG_H ++#define _FAILLOCK_CONFIG_H ++ ++#include ++#include ++#include ++ ++#include ++ ++#define FAILLOCK_FLAG_DENY_ROOT 0x1 ++#define FAILLOCK_FLAG_AUDIT 0x2 ++#define FAILLOCK_FLAG_SILENT 0x4 ++#define FAILLOCK_FLAG_NO_LOG_INFO 0x8 ++#define FAILLOCK_FLAG_UNLOCKED 0x10 ++#define FAILLOCK_FLAG_LOCAL_ONLY 0x20 ++#define FAILLOCK_FLAG_NO_DELAY 0x40 ++ ++#define FAILLOCK_CONF_MAX_LINELEN 1023 ++#define MAX_TIME_INTERVAL 604800 /* 7 days */ ++ ++struct options { ++ unsigned int action; ++ unsigned int flags; ++ unsigned short deny; ++ unsigned int fail_interval; ++ unsigned int unlock_time; ++ unsigned int root_unlock_time; ++ char *dir; ++ const char *user; ++ char *admin_group; ++ int failures; ++ uint64_t latest_time; ++ uid_t uid; ++ int is_admin; ++ uint64_t now; ++ int fatal_error; ++ ++ unsigned int reset; ++ const char *progname; ++ int legacy_output; /* show failure info in pam_tally2 style */ ++}; ++ ++int read_config_file(pam_handle_t *pamh, struct options *opts, ++ const char *cfgfile); ++void set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, ++ const char *value); ++const char *get_tally_dir(const struct options *opts); ++ ++#endif /* _FAILLOCK_CONFIG_H */ diff --git a/modules/pam_faillock/main.c b/modules/pam_faillock/main.c -index f62e1bb2..ea6329ca 100644 +index f62e1bb2..136be834 100644 --- a/modules/pam_faillock/main.c +++ b/modules/pam_faillock/main.c -@@ -174,6 +174,11 @@ do_user(struct options *opts, const char *user) - time_t when = tallies.records[i].time; - - tm = localtime(&when); -+ if(tm == NULL) { -+ fprintf(stderr, "%s: Invalid timestamp in the tally record\n", -+ opts->progname); -+ continue; +@@ -51,32 +51,40 @@ + #define AUDIT_NO_ID ((unsigned int) -1) + #endif + ++#include "pam_inline.h" + #include "faillock.h" +- +-struct options { +- unsigned int reset; +- const char *dir; +- const char *user; +- const char *progname; +-}; ++#include "faillock_config.h" + + static int + args_parse(int argc, char **argv, struct options *opts) + { + int i; ++ int rv; ++ const char *dir = NULL; ++ const char *conf = NULL; ++ + memset(opts, 0, sizeof(*opts)); + +- opts->dir = FAILLOCK_DEFAULT_TALLYDIR; + opts->progname = argv[0]; + + for (i = 1; i < argc; ++i) { +- if (strcmp(argv[i], "--dir") == 0) { ++ if (strcmp(argv[i], "--conf") == 0) { ++ ++i; ++ if (i >= argc || strlen(argv[i]) == 0) { ++ fprintf(stderr, "%s: No configuration file supplied.\n", ++ argv[0]); ++ return -1; + } - strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); - printf("%-19s %-5s %-52.52s %s\n", timebuf, - status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"), ++ conf = argv[i]; ++ } ++ else if (strcmp(argv[i], "--dir") == 0) { + ++i; + if (i >= argc || strlen(argv[i]) == 0) { +- fprintf(stderr, "%s: No directory supplied.\n", argv[0]); ++ fprintf(stderr, "%s: No records directory supplied.\n", ++ argv[0]); + return -1; + } +- opts->dir = argv[i]; ++ dir = argv[i]; + } + else if (strcmp(argv[i], "--user") == 0) { + ++i; +@@ -89,19 +97,113 @@ args_parse(int argc, char **argv, struct options *opts) + else if (strcmp(argv[i], "--reset") == 0) { + opts->reset = 1; + } ++ else if (!strcmp(argv[i], "--legacy-output")) { ++ opts->legacy_output = 1; ++ } + else { + fprintf(stderr, "%s: Unknown option: %s\n", argv[0], argv[i]); + return -1; + } + } ++ ++ if ((rv = read_config_file(NULL, opts, conf)) != PAM_SUCCESS) { ++ fprintf(stderr, "Configuration file missing or broken"); ++ return rv; ++ } ++ ++ if (dir != NULL) { ++ free(opts->dir); ++ opts->dir = strdup(dir); ++ if (opts->dir == NULL) { ++ fprintf(stderr, "Error allocating memory: %m"); ++ return -1; ++ } ++ } ++ + return 0; + } + + static void + usage(const char *progname) + { +- fprintf(stderr, _("Usage: %s [--dir /path/to/tally-directory] [--user username] [--reset]\n"), +- progname); ++ fprintf(stderr, ++ _("Usage: %s [--dir /path/to/tally-directory]" ++ " [--user username] [--reset] [--legacy-output]\n"), progname); ++ ++} ++ ++static int ++get_local_time(time_t when, char *timebuf, size_t timebuf_size) ++{ ++ struct tm *tm; ++ ++ tm = localtime(&when); ++ if (tm == NULL) { ++ return -1; ++ } ++ strftime(timebuf, timebuf_size, "%Y-%m-%d %H:%M:%S", tm); ++ return 0; ++} ++ ++static void ++print_in_new_format(struct options *opts, const struct tally_data *tallies, const char *user) ++{ ++ uint32_t i; ++ ++ printf("%s:\n", user); ++ printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid"); ++ ++ for (i = 0; i < tallies->count; i++) { ++ uint16_t status; ++ char timebuf[80]; ++ ++ if (get_local_time(tallies->records[i].time, timebuf, sizeof(timebuf)) != 0) { ++ fprintf(stderr, "%s: Invalid timestamp in the tally record\n", ++ opts->progname); ++ continue; ++ } ++ ++ status = tallies->records[i].status; ++ ++ printf("%-19s %-5s %-52.52s %s\n", timebuf, ++ status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"), ++ tallies->records[i].source, status & TALLY_STATUS_VALID ? "V":"I"); ++ } ++} ++ ++static void ++print_in_legacy_format(struct options *opts, const struct tally_data *tallies, const char *user) ++{ ++ uint32_t tally_count; ++ static uint32_t pr_once; ++ ++ if (pr_once == 0) { ++ printf(_("Login Failures Latest failure From\n")); ++ pr_once = 1; ++ } ++ ++ printf("%-15.15s ", user); ++ ++ tally_count = tallies->count; ++ ++ if (tally_count > 0) { ++ uint32_t i; ++ char timebuf[80]; ++ ++ i = tally_count - 1; ++ ++ if (get_local_time(tallies->records[i].time, timebuf, sizeof(timebuf)) != 0) { ++ fprintf(stderr, "%s: Invalid timestamp in the tally record\n", ++ opts->progname); ++ return; ++ } ++ ++ printf("%5u %25s %s\n", ++ tally_count, timebuf, tallies->records[i].source); ++ } ++ else { ++ printf("%5u\n", tally_count); ++ } + } + + static int +@@ -111,10 +213,15 @@ do_user(struct options *opts, const char *user) + int rv; + struct tally_data tallies; + struct passwd *pwd; ++ const char *dir = get_tally_dir(opts); + + pwd = getpwnam(user); ++ if (pwd == NULL) { ++ fprintf(stderr, "%s: Error no such user: %s\n", opts->progname, user); ++ return 1; ++ } + +- fd = open_tally(opts->dir, user, pwd != NULL ? pwd->pw_uid : 0, 0); ++ fd = open_tally(dir, user, pwd->pw_uid, 1); + + if (fd == -1) { + if (errno == ENOENT) { +@@ -153,8 +260,6 @@ do_user(struct options *opts, const char *user) + } + } + else { +- unsigned int i; +- + memset(&tallies, 0, sizeof(tallies)); + if (read_tally(fd, &tallies) == -1) { + fprintf(stderr, "%s: Error reading the tally file for %s:", +@@ -164,21 +269,13 @@ do_user(struct options *opts, const char *user) + return 5; + } + +- printf("%s:\n", user); +- printf("%-19s %-5s %-48s %-5s\n", "When", "Type", "Source", "Valid"); +- +- for (i = 0; i < tallies.count; i++) { +- struct tm *tm; +- char timebuf[80]; +- uint16_t status = tallies.records[i].status; +- time_t when = tallies.records[i].time; +- +- tm = localtime(&when); +- strftime(timebuf, sizeof(timebuf), "%Y-%m-%d %H:%M:%S", tm); +- printf("%-19s %-5s %-52.52s %s\n", timebuf, +- status & TALLY_STATUS_RHOST ? "RHOST" : (status & TALLY_STATUS_TTY ? "TTY" : "SVC"), +- tallies.records[i].source, status & TALLY_STATUS_VALID ? "V":"I"); ++ if (opts->legacy_output == 0) { ++ print_in_new_format(opts, &tallies, user); + } ++ else { ++ print_in_legacy_format(opts, &tallies, user); ++ } ++ + free(tallies.records); + } + close(fd); +@@ -190,8 +287,9 @@ do_allusers(struct options *opts) + { + struct dirent **userlist; + int rv, i; ++ const char *dir = get_tally_dir(opts); + +- rv = scandir(opts->dir, &userlist, NULL, alphasort); ++ rv = scandir(dir, &userlist, NULL, alphasort); + if (rv < 0) { + fprintf(stderr, "%s: Error reading tally directory: %m\n", opts->progname); + return 2; diff --git a/modules/pam_faillock/pam_faillock.8.xml b/modules/pam_faillock/pam_faillock.8.xml -index 58c16442..79bcbbd0 100644 +index 58c16442..b7b7b0db 100644 --- a/modules/pam_faillock/pam_faillock.8.xml +++ b/modules/pam_faillock/pam_faillock.8.xml @@ -134,10 +134,17 @@ @@ -424,7 +2710,20 @@ index 58c16442..79bcbbd0 100644 -@@ -328,6 +335,15 @@ session required pam_selinux.so open +@@ -320,6 +327,12 @@ session required pam_selinux.so open + /var/run/faillock/* + + the files logging the authentication failures for users ++ ++ Note: These files will disappear after reboot on systems configured with ++ directory /var/run/faillock mounted on virtual memory. ++ For persistent storage use the option dir= in ++ file /etc/security/faillock.conf. ++ + + + +@@ -328,6 +341,15 @@ session required pam_selinux.so open the config file for pam_faillock options @@ -439,27 +2738,327 @@ index 58c16442..79bcbbd0 100644 + - + diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c -index 8328fbae..932d4281 100644 +index 8328fbae..ca1c7035 100644 --- a/modules/pam_faillock/pam_faillock.c +++ b/modules/pam_faillock/pam_faillock.c -@@ -192,6 +192,15 @@ read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile) - char linebuf[FAILLOCK_CONF_MAX_LINELEN+1]; - - f = fopen(cfgfile, "r"); -+#ifdef VENDOR_FAILLOCK_DEFAULT_CONF -+ if (f == NULL && errno == ENOENT && cfgfile == default_faillock_conf) { -+ /* -+ * If the default configuration file in /etc does not exist, -+ * try the vendor configuration file as fallback. -+ */ -+ f = fopen(VENDOR_FAILLOCK_DEFAULT_CONF, "r"); -+ } -+#endif - if (f == NULL) { - /* ignore non-existent default config file */ - if (errno == ENOENT && cfgfile == default_faillock_conf) +@@ -38,7 +38,6 @@ + #include + #include + #include +-#include + #include + #include + #include +@@ -56,55 +55,12 @@ + + #include "pam_inline.h" + #include "faillock.h" ++#include "faillock_config.h" + + #define FAILLOCK_ACTION_PREAUTH 0 + #define FAILLOCK_ACTION_AUTHSUCC 1 + #define FAILLOCK_ACTION_AUTHFAIL 2 + +-#define FAILLOCK_FLAG_DENY_ROOT 0x1 +-#define FAILLOCK_FLAG_AUDIT 0x2 +-#define FAILLOCK_FLAG_SILENT 0x4 +-#define FAILLOCK_FLAG_NO_LOG_INFO 0x8 +-#define FAILLOCK_FLAG_UNLOCKED 0x10 +-#define FAILLOCK_FLAG_LOCAL_ONLY 0x20 +-#define FAILLOCK_FLAG_NO_DELAY 0x40 +- +-#define MAX_TIME_INTERVAL 604800 /* 7 days */ +-#define FAILLOCK_CONF_MAX_LINELEN 1023 +- +-static const char default_faillock_conf[] = FAILLOCK_DEFAULT_CONF; +- +-struct options { +- unsigned int action; +- unsigned int flags; +- unsigned short deny; +- unsigned int fail_interval; +- unsigned int unlock_time; +- unsigned int root_unlock_time; +- char *dir; +- const char *user; +- char *admin_group; +- int failures; +- uint64_t latest_time; +- uid_t uid; +- int is_admin; +- uint64_t now; +- int fatal_error; +-}; +- +-static int read_config_file( +- pam_handle_t *pamh, +- struct options *opts, +- const char *cfgfile +-); +- +-static void set_conf_opt( +- pam_handle_t *pamh, +- struct options *opts, +- const char *name, +- const char *value +-); +- + static int + args_parse(pam_handle_t *pamh, int argc, const char **argv, + int flags, struct options *opts) +@@ -112,11 +68,10 @@ args_parse(pam_handle_t *pamh, int argc, const char **argv, + int i; + int config_arg_index = -1; + int rv; +- const char *conf = default_faillock_conf; ++ const char *conf = NULL; + + memset(opts, 0, sizeof(*opts)); + +- opts->dir = strdup(FAILLOCK_DEFAULT_TALLYDIR); + opts->deny = 3; + opts->fail_interval = 900; + opts->unlock_time = 600; +@@ -174,185 +129,11 @@ args_parse(pam_handle_t *pamh, int argc, const char **argv, + if (flags & PAM_SILENT) + opts->flags |= FAILLOCK_FLAG_SILENT; + +- if (opts->dir == NULL) { +- pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m"); +- opts->fatal_error = 1; +- } +- + if (opts->fatal_error) + return PAM_BUF_ERR; + return PAM_SUCCESS; + } + +-/* parse a single configuration file */ +-static int +-read_config_file(pam_handle_t *pamh, struct options *opts, const char *cfgfile) +-{ +- FILE *f; +- char linebuf[FAILLOCK_CONF_MAX_LINELEN+1]; +- +- f = fopen(cfgfile, "r"); +- if (f == NULL) { +- /* ignore non-existent default config file */ +- if (errno == ENOENT && cfgfile == default_faillock_conf) +- return PAM_SUCCESS; +- return PAM_SERVICE_ERR; +- } +- +- while (fgets(linebuf, sizeof(linebuf), f) != NULL) { +- size_t len; +- char *ptr; +- char *name; +- int eq; +- +- len = strlen(linebuf); +- /* len cannot be 0 unless there is a bug in fgets */ +- if (len && linebuf[len - 1] != '\n' && !feof(f)) { +- (void) fclose(f); +- return PAM_SERVICE_ERR; +- } +- +- if ((ptr=strchr(linebuf, '#')) != NULL) { +- *ptr = '\0'; +- } else { +- ptr = linebuf + len; +- } +- +- /* drop terminating whitespace including the \n */ +- while (ptr > linebuf) { +- if (!isspace(*(ptr-1))) { +- *ptr = '\0'; +- break; +- } +- --ptr; +- } +- +- /* skip initial whitespace */ +- for (ptr = linebuf; isspace(*ptr); ptr++); +- if (*ptr == '\0') +- continue; +- +- /* grab the key name */ +- eq = 0; +- name = ptr; +- while (*ptr != '\0') { +- if (isspace(*ptr) || *ptr == '=') { +- eq = *ptr == '='; +- *ptr = '\0'; +- ++ptr; +- break; +- } +- ++ptr; +- } +- +- /* grab the key value */ +- while (*ptr != '\0') { +- if (*ptr != '=' || eq) { +- if (!isspace(*ptr)) { +- break; +- } +- } else { +- eq = 1; +- } +- ++ptr; +- } +- +- /* set the key:value pair on opts */ +- set_conf_opt(pamh, opts, name, ptr); +- } +- +- (void)fclose(f); +- return PAM_SUCCESS; +-} +- +-static void +-set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const char *value) +-{ +- if (strcmp(name, "dir") == 0) { +- if (value[0] != '/') { +- pam_syslog(pamh, LOG_ERR, +- "Tally directory is not absolute path (%s); keeping default", value); +- } else { +- free(opts->dir); +- opts->dir = strdup(value); +- } +- } +- else if (strcmp(name, "deny") == 0) { +- if (sscanf(value, "%hu", &opts->deny) != 1) { +- pam_syslog(pamh, LOG_ERR, +- "Bad number supplied for deny argument"); +- } +- } +- else if (strcmp(name, "fail_interval") == 0) { +- unsigned int temp; +- if (sscanf(value, "%u", &temp) != 1 || +- temp > MAX_TIME_INTERVAL) { +- pam_syslog(pamh, LOG_ERR, +- "Bad number supplied for fail_interval argument"); +- } else { +- opts->fail_interval = temp; +- } +- } +- else if (strcmp(name, "unlock_time") == 0) { +- unsigned int temp; +- +- if (strcmp(value, "never") == 0) { +- opts->unlock_time = 0; +- } +- else if (sscanf(value, "%u", &temp) != 1 || +- temp > MAX_TIME_INTERVAL) { +- pam_syslog(pamh, LOG_ERR, +- "Bad number supplied for unlock_time argument"); +- } +- else { +- opts->unlock_time = temp; +- } +- } +- else if (strcmp(name, "root_unlock_time") == 0) { +- unsigned int temp; +- +- if (strcmp(value, "never") == 0) { +- opts->root_unlock_time = 0; +- } +- else if (sscanf(value, "%u", &temp) != 1 || +- temp > MAX_TIME_INTERVAL) { +- pam_syslog(pamh, LOG_ERR, +- "Bad number supplied for root_unlock_time argument"); +- } else { +- opts->root_unlock_time = temp; +- } +- } +- else if (strcmp(name, "admin_group") == 0) { +- free(opts->admin_group); +- opts->admin_group = strdup(value); +- if (opts->admin_group == NULL) { +- opts->fatal_error = 1; +- pam_syslog(pamh, LOG_CRIT, "Error allocating memory: %m"); +- } +- } +- else if (strcmp(name, "even_deny_root") == 0) { +- opts->flags |= FAILLOCK_FLAG_DENY_ROOT; +- } +- else if (strcmp(name, "audit") == 0) { +- opts->flags |= FAILLOCK_FLAG_AUDIT; +- } +- else if (strcmp(name, "silent") == 0) { +- opts->flags |= FAILLOCK_FLAG_SILENT; +- } +- else if (strcmp(name, "no_log_info") == 0) { +- opts->flags |= FAILLOCK_FLAG_NO_LOG_INFO; +- } +- else if (strcmp(name, "local_users_only") == 0) { +- opts->flags |= FAILLOCK_FLAG_LOCAL_ONLY; +- } +- else if (strcmp(name, "nodelay") == 0) { +- opts->flags |= FAILLOCK_FLAG_NO_DELAY; +- } +- else { +- pam_syslog(pamh, LOG_ERR, "Unknown option: %s", name); +- } +-} +- + static int + check_local_user (pam_handle_t *pamh, const char *user) + { +@@ -406,10 +187,11 @@ check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies + unsigned int i; + uint64_t latest_time; + int failures; ++ const char *dir = get_tally_dir(opts); + + opts->now = time(NULL); + +- tfd = open_tally(opts->dir, opts->user, opts->uid, 0); ++ tfd = open_tally(dir, opts->user, opts->uid, 0); + + *fd = tfd; + +@@ -483,9 +265,10 @@ static void + reset_tally(pam_handle_t *pamh, struct options *opts, int *fd) + { + int rv; ++ const char *dir = get_tally_dir(opts); + + if (*fd == -1) { +- *fd = open_tally(opts->dir, opts->user, opts->uid, 1); ++ *fd = open_tally(dir, opts->user, opts->uid, 1); + } + else { + while ((rv=ftruncate(*fd, 0)) == -1 && errno == EINTR); +@@ -504,9 +287,10 @@ write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies + unsigned int oldest; + uint64_t oldtime; + const void *source = NULL; ++ const char *dir = get_tally_dir(opts); + + if (*fd == -1) { +- *fd = open_tally(opts->dir, opts->user, opts->uid, 1); ++ *fd = open_tally(dir, opts->user, opts->uid, 1); + } + if (*fd == -1) { + if (errno == EACCES) { +@@ -590,9 +374,11 @@ write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies + } + close(audit_fd); + #endif +- if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO)) { +- pam_syslog(pamh, LOG_INFO, "Consecutive login failures for user %s account temporarily locked", +- opts->user); ++ if (!(opts->flags & FAILLOCK_FLAG_NO_LOG_INFO) && ++ ((opts->flags & FAILLOCK_FLAG_DENY_ROOT) || (opts->uid != 0))) { ++ pam_syslog(pamh, LOG_INFO, ++ "Consecutive login failures for user %s account temporarily locked", ++ opts->user); + } + } + diff --git a/modules/pam_faillock/tst-pam_faillock-retval.c b/modules/pam_faillock/tst-pam_faillock-retval.c new file mode 100644 index 00000000..133026cb @@ -591,7 +3190,7 @@ index a9a0a1ef..fd88b952 100644 +++ b/modules/pam_group/Makefile.am @@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_GROUP_CONF=\"$(SCONFIGDIR)/group.conf\" $(WARN_CFLAGS) + $(WARN_CFLAGS) @@ -622,23 +3221,23 @@ index d9a35ea6..c49358a1 100644 #include #include +#include - + #include #include @@ -23,6 +24,10 @@ #include #include - + +#define PAM_GROUP_CONF SCONFIGDIR "/group.conf" +#ifdef VENDOR_SCONFIGDIR +# define VENDOR_PAM_GROUP_CONF VENDOR_SCONFIGDIR "/group.conf" +#endif #define PAM_GROUP_BUFLEN 1000 #define FIELD_SEPARATOR ';' /* this is new as of .02 */ - + @@ -70,7 +75,8 @@ trim_spaces(char *buf, char *from) #define STATE_EOF 3 /* end of file or error */ - + static int -read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state) +read_field(const pam_handle_t *pamh, int fd, char **buf, int *from, int *state, @@ -683,31 +3282,31 @@ index d9a35ea6..c49358a1 100644 + conf_filename = VENDOR_PAM_GROUP_CONF; + } +#endif - + /* * first we get the current list of groups - the application @@ -611,7 +629,7 @@ static int check_account(pam_handle_t *pamh, const char *service, - + /* here we get the service name field */ - + - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (!buffer || !buffer[0]) { /* empty line .. ? */ continue; @@ -621,7 +639,7 @@ static int check_account(pam_handle_t *pamh, const char *service, - + if (state != STATE_FIELD) { pam_syslog(pamh, LOG_ERR, - "%s: malformed rule #%d", PAM_GROUP_CONF, count); + "%s: malformed rule #%d", conf_filename, count); continue; } - + @@ -630,10 +648,10 @@ static int check_account(pam_handle_t *pamh, const char *service, - + /* here we get the terminal name field */ - + - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { @@ -718,9 +3317,9 @@ index d9a35ea6..c49358a1 100644 } good &= logic_field(pamh,tty, buffer, count, is_same); @@ -641,10 +659,10 @@ static int check_account(pam_handle_t *pamh, const char *service, - + /* here we get the username field */ - + - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { @@ -731,9 +3330,9 @@ index d9a35ea6..c49358a1 100644 } /* If buffer starts with @, we are using netgroups */ @@ -663,20 +681,20 @@ static int check_account(pam_handle_t *pamh, const char *service, - + /* here we get the time field */ - + - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state != STATE_FIELD) { @@ -742,10 +3341,10 @@ index d9a35ea6..c49358a1 100644 + "%s: malformed rule #%d", conf_filename, count); continue; } - + good &= logic_field(pamh,&here_and_now, buffer, count, check_time); D(("with time: %s", good ? "passes":"fails" )); - + - fd = read_field(pamh, fd, &buffer, &from, &state); + fd = read_field(pamh, fd, &buffer, &from, &state, conf_filename); if (state == STATE_FIELD) { @@ -754,14 +3353,442 @@ index d9a35ea6..c49358a1 100644 + "%s: poorly terminated rule #%d", conf_filename, count); continue; } - + +diff --git a/modules/pam_issue/pam_issue.c b/modules/pam_issue/pam_issue.c +index 5b6a4669..2f53440f 100644 +--- a/modules/pam_issue/pam_issue.c ++++ b/modules/pam_issue/pam_issue.c +@@ -36,98 +36,6 @@ + + static int _user_prompt_set = 0; + +-static int read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt); +-static int read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt); +- +-/* --- authentication management functions (only) --- */ +- +-int +-pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, +- int argc, const char **argv) +-{ +- int retval = PAM_SERVICE_ERR; +- FILE *fp; +- const char *issue_file = NULL; +- int parse_esc = 1; +- const void *item = NULL; +- const char *cur_prompt; +- char *issue_prompt = NULL; +- +- /* If we've already set the prompt, don't set it again */ +- if(_user_prompt_set) +- return PAM_IGNORE; +- +- /* We set this here so if we fail below, we won't get further +- than this next time around (only one real failure) */ +- _user_prompt_set = 1; +- +- for ( ; argc-- > 0 ; ++argv ) { +- const char *str; +- +- if ((str = pam_str_skip_prefix(*argv, "issue=")) != NULL) { +- issue_file = str; +- D(("set issue_file to: %s", issue_file)); +- } else if (!strcmp(*argv,"noesc")) { +- parse_esc = 0; +- D(("turning off escape parsing by request")); +- } else +- D(("unknown option passed: %s", *argv)); +- } +- +- if (issue_file == NULL) +- issue_file = "/etc/issue"; +- +- if ((fp = fopen(issue_file, "r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "error opening %s: %m", issue_file); +- return PAM_SERVICE_ERR; +- } +- +- if ((retval = pam_get_item(pamh, PAM_USER_PROMPT, &item)) != PAM_SUCCESS) { +- fclose(fp); +- return retval; +- } +- +- cur_prompt = item; +- if (cur_prompt == NULL) +- cur_prompt = ""; +- +- if (parse_esc) +- retval = read_issue_quoted(pamh, fp, &issue_prompt); +- else +- retval = read_issue_raw(pamh, fp, &issue_prompt); +- +- fclose(fp); +- +- if (retval != PAM_SUCCESS) +- goto out; +- +- { +- size_t size = strlen(issue_prompt) + strlen(cur_prompt) + 1; +- char *new_prompt = realloc(issue_prompt, size); +- +- if (new_prompt == NULL) { +- pam_syslog(pamh, LOG_CRIT, "out of memory"); +- retval = PAM_BUF_ERR; +- goto out; +- } +- issue_prompt = new_prompt; +- } +- +- strcat(issue_prompt, cur_prompt); +- retval = pam_set_item(pamh, PAM_USER_PROMPT, +- (const void *) issue_prompt); +- out: +- _pam_drop(issue_prompt); +- return (retval == PAM_SUCCESS) ? PAM_IGNORE : retval; +-} +- +-int +-pam_sm_setcred (pam_handle_t *pamh UNUSED, int flags UNUSED, +- int argc UNUSED, const char **argv UNUSED) +-{ +- return PAM_IGNORE; +-} +- + static int + read_issue_raw(pam_handle_t *pamh, FILE *fp, char **prompt) + { +@@ -303,4 +211,91 @@ read_issue_quoted(pam_handle_t *pamh, FILE *fp, char **prompt) + return PAM_SUCCESS; + } + +-/* end of module definition */ ++/* --- authentication management functions (only) --- */ ++ ++int ++pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, ++ int argc, const char **argv) ++{ ++ int retval = PAM_SERVICE_ERR; ++ FILE *fp; ++ const char *issue_file = NULL; ++ int parse_esc = 1; ++ const void *item = NULL; ++ const char *cur_prompt; ++ char *issue_prompt = NULL; ++ ++ /* If we've already set the prompt, don't set it again */ ++ if(_user_prompt_set) ++ return PAM_IGNORE; ++ ++ /* We set this here so if we fail below, we won't get further ++ than this next time around (only one real failure) */ ++ _user_prompt_set = 1; ++ ++ for ( ; argc-- > 0 ; ++argv ) { ++ const char *str; ++ ++ if ((str = pam_str_skip_prefix(*argv, "issue=")) != NULL) { ++ issue_file = str; ++ D(("set issue_file to: %s", issue_file)); ++ } else if (!strcmp(*argv,"noesc")) { ++ parse_esc = 0; ++ D(("turning off escape parsing by request")); ++ } else ++ D(("unknown option passed: %s", *argv)); ++ } ++ ++ if (issue_file == NULL) ++ issue_file = "/etc/issue"; ++ ++ if ((fp = fopen(issue_file, "r")) == NULL) { ++ pam_syslog(pamh, LOG_ERR, "error opening %s: %m", issue_file); ++ return PAM_SERVICE_ERR; ++ } ++ ++ if ((retval = pam_get_item(pamh, PAM_USER_PROMPT, &item)) != PAM_SUCCESS) { ++ fclose(fp); ++ return retval; ++ } ++ ++ cur_prompt = item; ++ if (cur_prompt == NULL) ++ cur_prompt = ""; ++ ++ if (parse_esc) ++ retval = read_issue_quoted(pamh, fp, &issue_prompt); ++ else ++ retval = read_issue_raw(pamh, fp, &issue_prompt); ++ ++ fclose(fp); ++ ++ if (retval != PAM_SUCCESS) ++ goto out; ++ ++ { ++ size_t size = strlen(issue_prompt) + strlen(cur_prompt) + 1; ++ char *new_prompt = realloc(issue_prompt, size); ++ ++ if (new_prompt == NULL) { ++ pam_syslog(pamh, LOG_CRIT, "out of memory"); ++ retval = PAM_BUF_ERR; ++ goto out; ++ } ++ issue_prompt = new_prompt; ++ } ++ ++ strcat(issue_prompt, cur_prompt); ++ retval = pam_set_item(pamh, PAM_USER_PROMPT, ++ (const void *) issue_prompt); ++ out: ++ _pam_drop(issue_prompt); ++ return (retval == PAM_SUCCESS) ? PAM_IGNORE : retval; ++} ++ ++int ++pam_sm_setcred(pam_handle_t *pamh UNUSED, int flags UNUSED, ++ int argc UNUSED, const char **argv UNUSED) ++{ ++ return PAM_IGNORE; ++} +diff --git a/modules/pam_keyinit/pam_keyinit.c b/modules/pam_keyinit/pam_keyinit.c +index 92e4953b..df9804b9 100644 +--- a/modules/pam_keyinit/pam_keyinit.c ++++ b/modules/pam_keyinit/pam_keyinit.c +@@ -21,6 +21,7 @@ + #include + #include + #include ++#include + + #define KEY_SPEC_SESSION_KEYRING -3 /* ID for session keyring */ + #define KEY_SPEC_USER_KEYRING -4 /* ID for UID-specific keyring */ +@@ -31,12 +32,12 @@ + #define KEYCTL_REVOKE 3 /* revoke a key */ + #define KEYCTL_LINK 8 /* link a key into a keyring */ + +-static int my_session_keyring = 0; +-static int session_counter = 0; +-static int do_revoke = 0; +-static uid_t revoke_as_uid; +-static gid_t revoke_as_gid; +-static int xdebug = 0; ++static _Thread_local int my_session_keyring = 0; ++static _Atomic int session_counter = 0; ++static _Thread_local int do_revoke = 0; ++static _Thread_local uid_t revoke_as_uid; ++static _Thread_local gid_t revoke_as_gid; ++static _Thread_local int xdebug = 0; + + static void debug(pam_handle_t *pamh, const char *fmt, ...) + __attribute__((format(printf, 2, 3))); +@@ -64,6 +65,33 @@ static void error(pam_handle_t *pamh, const char *fmt, ...) + va_end(va); + } + ++static int pam_setreuid(uid_t ruid, uid_t euid) ++{ ++#if defined(SYS_setreuid32) ++ return syscall(SYS_setreuid32, ruid, euid); ++#else ++ return syscall(SYS_setreuid, ruid, euid); ++#endif ++} ++ ++static int pam_setregid(gid_t rgid, gid_t egid) ++{ ++#if defined(SYS_setregid32) ++ return syscall(SYS_setregid32, rgid, egid); ++#else ++ return syscall(SYS_setregid, rgid, egid); ++#endif ++} ++ ++static int pam_setresuid(uid_t ruid, uid_t euid, uid_t suid) ++{ ++#if defined(SYS_setresuid32) ++ return syscall(SYS_setresuid32, ruid, euid, suid); ++#else ++ return syscall(SYS_setresuid, ruid, euid, suid); ++#endif ++} ++ + /* + * initialise the session keyring for this process + */ +@@ -140,14 +168,14 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret) + + /* switch to the real UID and GID so that we have permission to + * revoke the key */ +- if (revoke_as_gid != old_gid && setregid(-1, revoke_as_gid) < 0) { ++ if (revoke_as_gid != old_gid && pam_setregid(-1, revoke_as_gid) < 0) { + error(pamh, "Unable to change GID to %d temporarily\n", revoke_as_gid); + return error_ret; + } + +- if (revoke_as_uid != old_uid && setresuid(-1, revoke_as_uid, old_uid) < 0) { ++ if (revoke_as_uid != old_uid && pam_setresuid(-1, revoke_as_uid, old_uid) < 0) { + error(pamh, "Unable to change UID to %d temporarily\n", revoke_as_uid); +- if (getegid() != old_gid && setregid(-1, old_gid) < 0) ++ if (getegid() != old_gid && pam_setregid(-1, old_gid) < 0) + error(pamh, "Unable to change GID back to %d\n", old_gid); + return error_ret; + } +@@ -157,12 +185,12 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret) + } + + /* return to the original UID and GID (probably root) */ +- if (revoke_as_uid != old_uid && setreuid(-1, old_uid) < 0) { ++ if (revoke_as_uid != old_uid && pam_setreuid(-1, old_uid) < 0) { + error(pamh, "Unable to change UID back to %d\n", old_uid); + ret = error_ret; + } + +- if (revoke_as_gid != old_gid && setregid(-1, old_gid) < 0) { ++ if (revoke_as_gid != old_gid && pam_setregid(-1, old_gid) < 0) { + error(pamh, "Unable to change GID back to %d\n", old_gid); + ret = error_ret; + } +@@ -215,14 +243,14 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error + + /* switch to the real UID and GID so that the keyring ends up owned by + * the right user */ +- if (gid != old_gid && setregid(gid, -1) < 0) { ++ if (gid != old_gid && pam_setregid(gid, -1) < 0) { + error(pamh, "Unable to change GID to %d temporarily\n", gid); + return error_ret; + } + +- if (uid != old_uid && setreuid(uid, -1) < 0) { ++ if (uid != old_uid && pam_setreuid(uid, -1) < 0) { + error(pamh, "Unable to change UID to %d temporarily\n", uid); +- if (setregid(old_gid, -1) < 0) ++ if (pam_setregid(old_gid, -1) < 0) + error(pamh, "Unable to change GID back to %d\n", old_gid); + return error_ret; + } +@@ -230,12 +258,12 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error + ret = init_keyrings(pamh, force, error_ret); + + /* return to the original UID and GID (probably root) */ +- if (uid != old_uid && setreuid(old_uid, -1) < 0) { ++ if (uid != old_uid && pam_setreuid(old_uid, -1) < 0) { + error(pamh, "Unable to change UID back to %d\n", old_uid); + ret = error_ret; + } + +- if (gid != old_gid && setregid(old_gid, -1) < 0) { ++ if (gid != old_gid && pam_setregid(old_gid, -1) < 0) { + error(pamh, "Unable to change GID back to %d\n", old_gid); + ret = error_ret; + } +diff --git a/modules/pam_lastlog/pam_lastlog.c b/modules/pam_lastlog/pam_lastlog.c +index abd048df..797a61ce 100644 +--- a/modules/pam_lastlog/pam_lastlog.c ++++ b/modules/pam_lastlog/pam_lastlog.c +@@ -57,14 +57,13 @@ struct lastlog { + # define PATH_LOGIN_DEFS "/etc/login.defs" + #endif + +-/* XXX - time before ignoring lock. Is 1 sec enough? */ +-#define LASTLOG_IGNORE_LOCK_TIME 1 +- + #define DEFAULT_HOST "" /* "[no.where]" */ + #define DEFAULT_TERM "" /* "tt???" */ + + #define DEFAULT_INACTIVE_DAYS 90 + #define MAX_INACTIVE_DAYS 100000 ++#define LOCK_RETRIES 3 /* number of file lock retries */ ++#define LOCK_RETRY_DELAY 1 /* seconds to wait between lock attempts */ + + #include + #include +@@ -266,6 +265,7 @@ last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t + { + struct flock last_lock; + struct lastlog last_login; ++ int lock_retries = LOCK_RETRIES; + int retval = PAM_SUCCESS; + char the_time[256]; + char *date = NULL; +@@ -278,11 +278,19 @@ last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t + last_lock.l_start = sizeof(last_login) * (off_t) uid; + last_lock.l_len = sizeof(last_login); + +- if (fcntl(last_fd, F_SETLK, &last_lock) < 0) { ++ while (fcntl(last_fd, F_SETLK, &last_lock) < 0) { ++ if (0 == --lock_retries) { ++ /* read lock failed, proceed anyway to avoid possible DoS */ ++ D(("locking %s failed", _PATH_LASTLOG)); ++ pam_syslog(pamh, LOG_INFO, ++ "file %s is locked/read, proceeding anyway", ++ _PATH_LASTLOG); ++ break; ++ } + D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); +- pam_syslog(pamh, LOG_WARNING, +- "file %s is locked/read", _PATH_LASTLOG); +- sleep(LASTLOG_IGNORE_LOCK_TIME); ++ pam_syslog(pamh, LOG_INFO, ++ "file %s is locked/read, retrying", _PATH_LASTLOG); ++ sleep(LOCK_RETRY_DELAY); + } + + if (pam_modutil_read(last_fd, (char *) &last_login, +@@ -380,6 +388,7 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd, + int setrlimit_res; + struct flock last_lock; + struct lastlog last_login; ++ int lock_retries = LOCK_RETRIES; + time_t ll_time; + const void *void_remote_host = NULL; + const char *remote_host; +@@ -426,10 +435,17 @@ last_login_write(pam_handle_t *pamh, int announce, int last_fd, + last_lock.l_start = sizeof(last_login) * (off_t) uid; + last_lock.l_len = sizeof(last_login); + +- if (fcntl(last_fd, F_SETLK, &last_lock) < 0) { ++ while (fcntl(last_fd, F_SETLK, &last_lock) < 0) { ++ if (0 == --lock_retries) { ++ D(("locking %s failed", _PATH_LASTLOG)); ++ pam_syslog(pamh, LOG_ERR, ++ "file %s is locked/write", _PATH_LASTLOG); ++ return PAM_SERVICE_ERR; ++ } + D(("locking %s failed..(waiting a little)", _PATH_LASTLOG)); +- pam_syslog(pamh, LOG_WARNING, "file %s is locked/write", _PATH_LASTLOG); +- sleep(LASTLOG_IGNORE_LOCK_TIME); ++ pam_syslog(pamh, LOG_INFO, ++ "file %s is locked/write, retrying", _PATH_LASTLOG); ++ sleep(LOCK_RETRY_DELAY); + } + + /* +@@ -573,12 +589,12 @@ last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t llt + time_t lf_time; + + lf_time = utuser.ut_tv.tv_sec; +- tm = localtime_r (&lf_time, &tm_buf); +- strftime (the_time, sizeof (the_time), +- /* TRANSLATORS: "strftime options for date of last login" */ +- _(" %a %b %e %H:%M:%S %Z %Y"), tm); +- +- date = the_time; ++ if ((tm = localtime_r (&lf_time, &tm_buf)) != NULL) { ++ strftime (the_time, sizeof (the_time), ++ /* TRANSLATORS: "strftime options for date of last login" */ ++ _(" %a %b %e %H:%M:%S %Z %Y"), tm); ++ date = the_time; ++ } + } + + /* we want & have the host? */ diff --git a/modules/pam_limits/Makefile.am b/modules/pam_limits/Makefile.am index 911b07b3..9ae1794d 100644 --- a/modules/pam_limits/Makefile.am +++ b/modules/pam_limits/Makefile.am @@ -19,8 +19,8 @@ secureconfdir = $(SCONFIGDIR) limits_conf_dir = $(SCONFIGDIR)/limits.d - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DLIMITS_FILE_DIR=\"$(limits_conf_dir)/*.conf\" \ - -DLIMITS_FILE=\"$(SCONFIGDIR)/limits.conf\" $(WARN_CFLAGS) @@ -771,120 +3798,898 @@ index 911b07b3..9ae1794d 100644 if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map diff --git a/modules/pam_limits/pam_limits.8.xml b/modules/pam_limits/pam_limits.8.xml -index bc46cbf4..08c6fc4d 100644 +index bc46cbf4..422924fe 100644 --- a/modules/pam_limits/pam_limits.8.xml +++ b/modules/pam_limits/pam_limits.8.xml -@@ -57,6 +57,11 @@ +@@ -48,7 +48,7 @@ + obtained in a user-session. Users of uid=0 are affected + by this limits, too. + +- ++ + By default limits are taken from the /etc/security/limits.conf + config file. Then individual *.conf files from the /etc/security/limits.d/ + directory are read. The files are parsed one after another in the order of "C" locale. +@@ -57,6 +57,23 @@ If a config file is explicitly specified with a module option then the files in the above directory are not parsed. + -+ If there is no explicitly specified configuration file and -+ /etc/security/limits.conf does not exist, -+ %vendordir%/security/limits.conf is used. ++ By default limits are taken from the /etc/security/limits.conf ++ config file or, if that one is not present, the file ++ %vendordir%/security/limits.conf. ++ Then individual *.conf files from the ++ /etc/security/limits.d/ and ++ %vendordir%/security/limits.d directories are read. ++ If /etc/security/limits.d/@filename@.conf exists, then ++ %vendordir%/security/limits.d/@filename@.conf will not be used. ++ All limits.d/*.conf files are sorted by their ++ @filename@.conf in lexicographic order regardless of which ++ of the directories they reside in. ++ The effect of the individual files is the same as if all the files were ++ concatenated together in the order of parsing. ++ If a config file is explicitly specified with the ++ option the files in the above directories are not parsed. + The module must not be called by a multithreaded application. +@@ -211,6 +228,13 @@ + Default configuration file + + ++ ++ %vendordir%/security/limits.conf ++ ++ Default configuration file if ++ /etc/security/limits.conf does not exist. ++ ++ + + + diff --git a/modules/pam_limits/pam_limits.c b/modules/pam_limits/pam_limits.c -index 7cc45d77..6fbe95fc 100644 +index 7cc45d77..f9489dbe 100644 --- a/modules/pam_limits/pam_limits.c +++ b/modules/pam_limits/pam_limits.c @@ -47,6 +47,10 @@ #include #endif - + +#ifndef PR_SET_NO_NEW_PRIVS +# define PR_SET_NO_NEW_PRIVS 38 /* from */ +#endif + /* Module defines */ #define LINE_LENGTH 1024 - -@@ -119,9 +123,10 @@ struct pam_limit_s { + +@@ -119,9 +123,14 @@ struct pam_limit_s { #define PAM_SET_ALL 0x0010 - + /* Limits from globbed files. */ -#define LIMITS_CONF_GLOB LIMITS_FILE_DIR +#define LIMITS_CONF_GLOB (LIMITS_FILE_DIR "/*.conf") - --#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE ++ +#define LIMITS_FILE (SCONFIGDIR "/limits.conf") -+#define CONF_FILE ((pl->conf_file != NULL) ? pl->conf_file : LIMITS_FILE) - + +-#define CONF_FILE (pl->conf_file != NULL)?pl->conf_file:LIMITS_FILE ++#ifdef VENDOR_SCONFIGDIR ++#define VENDOR_LIMITS_FILE (VENDOR_SCONFIGDIR "/limits.conf") ++#define VENDOR_LIMITS_CONF_GLOB (VENDOR_SCONFIGDIR "/limits.d/*.conf") ++#endif + static int _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, -@@ -811,14 +816,30 @@ parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid, +@@ -806,18 +815,22 @@ parse_uid_range(pam_handle_t *pamh, const char *domain, + + static int + parse_config_file(pam_handle_t *pamh, const char *uname, uid_t uid, gid_t gid, +- int ctrl, struct pam_limit_s *pl) ++ int ctrl, struct pam_limit_s *pl, const int conf_file_set_by_user) + { FILE *fil; char buf[LINE_LENGTH]; - + - /* check for the LIMITS_FILE */ -+ /* check for the CONF_FILE */ ++ /* check for the conf_file */ if (ctrl & PAM_DEBUG_ARG) - pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE); - fil = fopen(CONF_FILE, "r"); +- pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", CONF_FILE); +- fil = fopen(CONF_FILE, "r"); ++ pam_syslog(pamh, LOG_DEBUG, "reading settings from '%s'", pl->conf_file); ++ fil = fopen(pl->conf_file, "r"); if (fil == NULL) { - pam_syslog (pamh, LOG_WARNING, - "cannot read settings from %s: %m", CONF_FILE); -- return PAM_SERVICE_ERR; -+ int err = errno; ++ if (errno == ENOENT && !conf_file_set_by_user) ++ return PAM_SUCCESS; /* file is not there and it has not been set by the conf= argument */ + -+#ifdef VENDOR_SCONFIGDIR -+ /* if the specified file does not exist, and it is not provided by -+ the user, try the vendor file as fallback. */ -+ if (pl->conf_file == NULL && err == ENOENT) -+ fil = fopen(VENDOR_SCONFIGDIR "/limits.conf", "r"); -+ -+ if (fil == NULL) -+#endif -+ { -+ if (err == ENOENT) -+ return PAM_SUCCESS; -+ -+ pam_syslog (pamh, LOG_WARNING, -+ "cannot read settings from %s: %s", CONF_FILE, -+ strerror(err)); -+ return PAM_SERVICE_ERR; -+ } ++ pam_syslog(pamh, LOG_WARNING, ++ "cannot read settings from %s: %s", pl->conf_file, ++ strerror(errno)); + return PAM_SERVICE_ERR; } - - /* start the show */ + +@@ -1074,33 +1087,132 @@ static int setup_limits(pam_handle_t *pamh, + return retval; + } + ++/* --- evaluting all files in VENDORDIR/security/limits.d and /etc/security/limits.d --- */ ++static const char * ++base_name(const char *path) ++{ ++ const char *base = strrchr(path, '/'); ++ return base ? base+1 : path; ++} ++ ++static int ++compare_filename(const void *a, const void *b) ++{ ++ return strcmp(base_name(* (const char * const *) a), ++ base_name(* (const char * const *) b)); ++} ++ ++/* Evaluating a list of files which have to be parsed in the right order: ++ * ++ * - If etc/security/limits.d/@filename@.conf exists, then ++ * %vendordir%/security/limits.d/@filename@.conf should not be used. ++ * - All files in both limits.d directories are sorted by their @filename@.conf in ++ * lexicographic order regardless of which of the directories they reside in. */ ++static char ** ++read_limits_dir(pam_handle_t *pamh) ++{ ++ glob_t globbuf; ++ size_t i=0; ++ int glob_rv = glob(LIMITS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf); ++ char **file_list; ++ size_t file_list_size = glob_rv == 0 ? globbuf.gl_pathc : 0; ++ ++#ifdef VENDOR_LIMITS_CONF_GLOB ++ glob_t globbuf_vendor; ++ int glob_rv_vendor = glob(VENDOR_LIMITS_CONF_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf_vendor); ++ if (glob_rv_vendor == 0) ++ file_list_size += globbuf_vendor.gl_pathc; ++#endif ++ file_list = malloc((file_list_size + 1) * sizeof(char*)); ++ if (file_list == NULL) { ++ pam_syslog(pamh, LOG_ERR, "Cannot allocate memory for file list: %m"); ++#ifdef VENDOR_ACCESS_CONF_GLOB ++ if (glob_rv_vendor == 0) ++ globfree(&globbuf_vendor); ++#endif ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ return NULL; ++ } ++ ++ if (glob_rv == 0) { ++ for (i = 0; i < globbuf.gl_pathc; i++) { ++ file_list[i] = strdup(globbuf.gl_pathv[i]); ++ if (file_list[i] == NULL) { ++ pam_syslog(pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ } ++ } ++#ifdef VENDOR_LIMITS_CONF_GLOB ++ if (glob_rv_vendor == 0) { ++ for (size_t j = 0; j < globbuf_vendor.gl_pathc; j++) { ++ if (glob_rv == 0 && globbuf.gl_pathc > 0) { ++ int double_found = 0; ++ for (size_t k = 0; k < globbuf.gl_pathc; k++) { ++ if (strcmp(base_name(globbuf.gl_pathv[k]), ++ base_name(globbuf_vendor.gl_pathv[j])) == 0) { ++ double_found = 1; ++ break; ++ } ++ } ++ if (double_found) ++ continue; ++ } ++ file_list[i] = strdup(globbuf_vendor.gl_pathv[j]); ++ if (file_list[i] == NULL) { ++ pam_syslog(pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ i++; ++ } ++ globfree(&globbuf_vendor); ++ } ++#endif ++ file_list[i] = NULL; ++ qsort(file_list, i, sizeof(char *), compare_filename); ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ ++ return file_list; ++} ++ + /* now the session stuff */ + int + pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, + int argc, const char **argv) + { +- int retval; +- int i; +- int glob_rc; ++ int retval, i; + char *user_name; + struct passwd *pwd; + int ctrl; + struct pam_limit_s plstruct; + struct pam_limit_s *pl = &plstruct; +- glob_t globbuf; +- const char *oldlocale; + + D(("called.")); + + memset(pl, 0, sizeof(*pl)); +- memset(&globbuf, 0, sizeof(globbuf)); + + ctrl = _pam_parse(pamh, argc, argv, pl); + retval = pam_get_item( pamh, PAM_USER, (void*) &user_name ); + if ( user_name == NULL || retval != PAM_SUCCESS ) { + pam_syslog(pamh, LOG_ERR, "open_session - error recovering username"); + return PAM_SESSION_ERR; +- } ++ } ++ ++ int conf_file_set_by_user = (pl->conf_file != NULL); ++ if (pl->conf_file == NULL) { ++ pl->conf_file = LIMITS_FILE; ++#ifdef VENDOR_LIMITS_FILE ++ /* ++ * Check whether LIMITS_FILE file is available. ++ * If it does not exist, fall back to VENDOR_LIMITS_FILE file. ++ */ ++ struct stat buffer; ++ if (stat(pl->conf_file, &buffer) != 0 && errno == ENOENT) ++ pl->conf_file = VENDOR_LIMITS_FILE; ++#endif ++ } + + pwd = pam_modutil_getpwnam(pamh, user_name); + if (!pwd) { +@@ -1116,46 +1228,39 @@ pam_sm_open_session (pam_handle_t *pamh, int flags UNUSED, + return PAM_ABORT; + } + +- retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl); ++ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ++ ctrl, pl, conf_file_set_by_user); + if (retval == PAM_IGNORE) { +- D(("the configuration file ('%s') has an applicable ' -' entry", CONF_FILE)); ++ D(("the configuration file ('%s') has an applicable ' -' entry", pl->conf_file)); + return PAM_SUCCESS; + } +- if (retval != PAM_SUCCESS || pl->conf_file != NULL) ++ if (retval != PAM_SUCCESS || conf_file_set_by_user) + /* skip reading limits.d if config file explicitly specified */ + goto out; + + /* Read subsequent *.conf files, if they exist. */ +- +- /* set the LC_COLLATE so the sorting order doesn't depend +- on system locale */ +- +- oldlocale = setlocale(LC_COLLATE, "C"); +- glob_rc = glob(LIMITS_CONF_GLOB, GLOB_ERR, NULL, &globbuf); +- +- if (oldlocale != NULL) +- setlocale (LC_COLLATE, oldlocale); +- +- if (!glob_rc) { +- /* Parse the *.conf files. */ +- for (i = 0; globbuf.gl_pathv[i] != NULL; i++) { +- pl->conf_file = globbuf.gl_pathv[i]; +- retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl); +- if (retval == PAM_IGNORE) { +- D(("the configuration file ('%s') has an applicable ' -' entry", pl->conf_file)); +- globfree(&globbuf); +- return PAM_SUCCESS; +- } +- if (retval != PAM_SUCCESS) +- goto out; ++ char **filename_list = read_limits_dir(pamh); ++ if (filename_list != NULL) { ++ for (i = 0; filename_list[i] != NULL; i++) { ++ pl->conf_file = filename_list[i]; ++ retval = parse_config_file(pamh, pwd->pw_name, pwd->pw_uid, pwd->pw_gid, ctrl, pl, 0); ++ if (retval != PAM_SUCCESS) ++ break; + } ++ for (i = 0; filename_list[i] != NULL; i++) ++ free(filename_list[i]); ++ free(filename_list); ++ } ++ ++ if (retval == PAM_IGNORE) { ++ D(("the configuration file ('%s') has an applicable ' -' entry", pl->conf_file)); ++ return PAM_SUCCESS; + } + + out: +- globfree(&globbuf); + if (retval != PAM_SUCCESS) + { +- pam_syslog(pamh, LOG_ERR, "error parsing the configuration file: '%s' ",CONF_FILE); ++ pam_syslog(pamh, LOG_ERR, "error parsing the configuration file: '%s' ", pl->conf_file); + return retval; + } + +diff --git a/modules/pam_mail/pam_mail.c b/modules/pam_mail/pam_mail.c +index 17383c7b..7eb94fc7 100644 +--- a/modules/pam_mail/pam_mail.c ++++ b/modules/pam_mail/pam_mail.c +@@ -286,7 +286,7 @@ report_mail(pam_handle_t *pamh, int ctrl, int type, const char *folder) + switch (type) + { + case HAVE_NO_MAIL: +- retval = pam_info (pamh, "%s", _("You have no mail.")); ++ retval = pam_info (pamh, "%s", _("You do not have any new mail.")); + break; + case HAVE_NEW_MAIL: + retval = pam_info (pamh, "%s", _("You have new mail.")); +diff --git a/modules/pam_mkhomedir/pam_mkhomedir.c b/modules/pam_mkhomedir/pam_mkhomedir.c +index 48e578fa..6ddcd5a8 100644 +--- a/modules/pam_mkhomedir/pam_mkhomedir.c ++++ b/modules/pam_mkhomedir/pam_mkhomedir.c +@@ -125,15 +125,6 @@ create_homedir (pam_handle_t *pamh, options_t *opt, + + D(("called.")); + +- /* +- * 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); +- + if (opt->ctrl & MKHOMEDIR_DEBUG) { + pam_syslog(pamh, LOG_DEBUG, "Executing mkhomedir_helper."); + } +@@ -153,6 +144,15 @@ create_homedir (pam_handle_t *pamh, options_t *opt, + login_homemode = _pam_conv_str_umask_to_homemode(opt->umask); + } + ++ /* ++ * 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); ++ + /* fork */ + child = fork(); + if (child == 0) { +diff --git a/modules/pam_motd/pam_motd.c b/modules/pam_motd/pam_motd.c +index 6ac8cba2..5ca486e4 100644 +--- a/modules/pam_motd/pam_motd.c ++++ b/modules/pam_motd/pam_motd.c +@@ -166,11 +166,6 @@ static int compare_strings(const void *a, const void *b) + } + } + +-static int filter_dirents(const struct dirent *d) +-{ +- return (d->d_type == DT_REG || d->d_type == DT_LNK); +-} +- + static void try_to_display_directories_with_overrides(pam_handle_t *pamh, + char **motd_dir_path_split, unsigned int num_motd_dirs, int report_missing) + { +@@ -199,8 +194,7 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh, + + for (i = 0; i < num_motd_dirs; i++) { + int rv; +- rv = scandir(motd_dir_path_split[i], &(dirscans[i]), +- filter_dirents, alphasort); ++ rv = scandir(motd_dir_path_split[i], &(dirscans[i]), NULL, NULL); + if (rv < 0) { + if (errno != ENOENT || report_missing) { + pam_syslog(pamh, LOG_ERR, "error scanning directory %s: %m", +@@ -215,6 +209,41 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh, + if (dirscans_size_total == 0) + goto out; + ++ /* filter out unwanted names, directories, and complement data with lstat() */ ++ for (i = 0; i < num_motd_dirs; i++) { ++ struct dirent **d = dirscans[i]; ++ for (unsigned int j = 0; j < dirscans_sizes[i]; j++) { ++ int rc; ++ char *fullpath; ++ struct stat s; ++ ++ switch(d[j]->d_type) { /* the filetype determines how to proceed */ ++ case DT_REG: /* regular files and */ ++ case DT_LNK: /* symlinks */ ++ continue; /* are good. */ ++ case DT_UNKNOWN: /* for file systems that do not provide */ ++ /* a filetype, we use lstat() */ ++ if (join_dir_strings(&fullpath, motd_dir_path_split[i], ++ d[j]->d_name) <= 0) ++ break; ++ rc = lstat(fullpath, &s); ++ _pam_drop(fullpath); /* free the memory alloc'ed by join_dir_strings */ ++ if (rc != 0) /* if the lstat() somehow failed */ ++ break; ++ ++ if (S_ISREG(s.st_mode) || /* regular files and */ ++ S_ISLNK(s.st_mode)) continue; /* symlinks are good */ ++ break; ++ case DT_DIR: /* We don't want directories */ ++ default: /* nor anything else */ ++ break; ++ } ++ _pam_drop(d[j]); /* free memory */ ++ d[j] = NULL; /* indicate this one was dropped */ ++ dirscans_size_total--; ++ } ++ } ++ + /* Allocate space for all file names found in the directories, including duplicates. */ + if ((dirnames_all = calloc(dirscans_size_total, sizeof(*dirnames_all))) == NULL) { + pam_syslog(pamh, LOG_CRIT, "failed to allocate dirname array"); +@@ -225,8 +254,10 @@ static void try_to_display_directories_with_overrides(pam_handle_t *pamh, + unsigned int j; + + for (j = 0; j < dirscans_sizes[i]; j++) { +- dirnames_all[i_dirnames] = dirscans[i][j]->d_name; +- i_dirnames++; ++ if (NULL != dirscans[i][j]) { ++ dirnames_all[i_dirnames] = dirscans[i][j]->d_name; ++ i_dirnames++; ++ } + } + } + diff --git a/modules/pam_namespace/Makefile.am b/modules/pam_namespace/Makefile.am index 47cc38e1..33375857 100644 --- a/modules/pam_namespace/Makefile.am +++ b/modules/pam_namespace/Makefile.am @@ -21,7 +21,7 @@ namespaceddir = $(SCONFIGDIR)/namespace.d servicedir = $(systemdunitdir) - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DSECURECONF_DIR=\"$(SCONFIGDIR)/\" $(WARN_CFLAGS) + $(WARN_CFLAGS) AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +diff --git a/modules/pam_namespace/namespace.conf.5.xml b/modules/pam_namespace/namespace.conf.5.xml +index a94b49e2..67f8c043 100644 +--- a/modules/pam_namespace/namespace.conf.5.xml ++++ b/modules/pam_namespace/namespace.conf.5.xml +@@ -30,13 +30,29 @@ + directory path and the instance directory path as its arguments. + + +- ++ + The /etc/security/namespace.conf file specifies + which directories are polyinstantiated, how they are polyinstantiated, + how instance directories would be named, and any users for whom + polyinstantiation would not be performed. + + ++ ++ The /etc/security/namespace.conf file ++ ( or %vendordir%/security/namespace.conf if it does ++ not exist) 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. ++ Then individual *.conf files from the ++ /etc/security/namespace.d/ and ++ %vendordir%/security/namespace.d directories are taken too. ++ If /etc/security/namespace.d/@filename@.conf exists, then ++ %vendordir%/security/namespace.d/@filename@.conf will not be used. ++ All namespace.d/*.conf files are sorted by their ++ @filename@.conf in lexicographic order regardless of which ++ of the directories they reside in. ++ ++ + + When someone logs in, the file namespace.conf is + scanned. Comments are marked by # characters. +diff --git a/modules/pam_namespace/pam_namespace.8.xml b/modules/pam_namespace/pam_namespace.8.xml +index 57c44c4b..ddaa00b4 100644 +--- a/modules/pam_namespace/pam_namespace.8.xml ++++ b/modules/pam_namespace/pam_namespace.8.xml +@@ -74,6 +74,12 @@ + and the user name as its arguments. + + ++ ++ If /etc/security/namespace.init does not exist, ++ %vendordir%/security/namespace.init is the ++ alternative to be used for it. ++ ++ + + The pam_namespace module disassociates the session namespace from + the parent namespace. Any mounts/unmounts performed in the parent +@@ -313,6 +319,14 @@ + + + ++ ++ %vendordir%/security/namespace.conf ++ ++ Default configuration file if ++ /etc/security/namespace.conf does not exist. ++ ++ ++ + + /etc/security/namespace.d + +@@ -320,12 +334,28 @@ + + + ++ ++ %vendordir%/security/namespace.d ++ ++ Directory for additional vendor specific configuration files. ++ ++ ++ + + /etc/security/namespace.init + + Init script for instance directories + + ++ ++ ++ %vendordir%/security/namespace.init ++ ++ Vendor init script for instance directories if ++ /etc/security/namespace.init does not exist. ++ ++ ++ + + + +diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c +index 4d4188d0..f34ce934 100644 +--- a/modules/pam_namespace/pam_namespace.c ++++ b/modules/pam_namespace/pam_namespace.c +@@ -39,6 +39,94 @@ + #include "pam_namespace.h" + #include "argv_parse.h" + ++/* --- evaluting all files in VENDORDIR/security/namespace.d and /etc/security/namespace.d --- */ ++static const char *base_name(const char *path) ++{ ++ const char *base = strrchr(path, '/'); ++ return base ? base+1 : path; ++} ++ ++static int ++compare_filename(const void *a, const void *b) ++{ ++ return strcmp(base_name(* (char * const *) a), ++ base_name(* (char * const *) b)); ++} ++ ++/* Evaluating a list of files which have to be parsed in the right order: ++ * ++ * - If etc/security/namespace.d/@filename@.conf exists, then ++ * %vendordir%/security/namespace.d/@filename@.conf should not be used. ++ * - All files in both namespace.d directories are sorted by their @filename@.conf in ++ * lexicographic order regardless of which of the directories they reside in. */ ++static char **read_namespace_dir(struct instance_data *idata) ++{ ++ glob_t globbuf; ++ size_t i=0; ++ int glob_rv = glob(NAMESPACE_D_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf); ++ char **file_list; ++ size_t file_list_size = glob_rv == 0 ? globbuf.gl_pathc : 0; ++ ++#ifdef VENDOR_NAMESPACE_D_GLOB ++ glob_t globbuf_vendor; ++ int glob_rv_vendor = glob(VENDOR_NAMESPACE_D_GLOB, GLOB_ERR | GLOB_NOSORT, NULL, &globbuf_vendor); ++ if (glob_rv_vendor == 0) ++ file_list_size += globbuf_vendor.gl_pathc; ++#endif ++ file_list = malloc((file_list_size + 1) * sizeof(char*)); ++ if (file_list == NULL) { ++ pam_syslog(idata->pamh, LOG_ERR, "Cannot allocate memory for file list: %m"); ++#ifdef VENDOR_NAMESPACE_D_GLOB ++ if (glob_rv_vendor == 0) ++ globfree(&globbuf_vendor); ++#endif ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ return NULL; ++ } ++ ++ if (glob_rv == 0) { ++ for (i = 0; i < globbuf.gl_pathc; i++) { ++ file_list[i] = strdup(globbuf.gl_pathv[i]); ++ if (file_list[i] == NULL) { ++ pam_syslog(idata->pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ } ++ } ++#ifdef VENDOR_NAMESPACE_D_GLOB ++ if (glob_rv_vendor == 0) { ++ for (size_t j = 0; j < globbuf_vendor.gl_pathc; j++) { ++ if (glob_rv == 0 && globbuf.gl_pathc > 0) { ++ int double_found = 0; ++ for (size_t k = 0; k < globbuf.gl_pathc; k++) { ++ if (strcmp(base_name(globbuf.gl_pathv[k]), ++ base_name(globbuf_vendor.gl_pathv[j])) == 0) { ++ double_found = 1; ++ break; ++ } ++ } ++ if (double_found) ++ continue; ++ } ++ file_list[i] = strdup(globbuf_vendor.gl_pathv[j]); ++ if (file_list[i] == NULL) { ++ pam_syslog(idata->pamh, LOG_ERR, "strdup failed: %m"); ++ break; ++ } ++ i++; ++ } ++ globfree(&globbuf_vendor); ++ } ++#endif ++ file_list[i] = NULL; ++ qsort(file_list, i, sizeof(char *), compare_filename); ++ if (glob_rv == 0) ++ globfree(&globbuf); ++ ++ return file_list; ++} ++ + /* + * Adds an entry for a polyinstantiated directory to the linked list of + * polyinstantiated directories. It is called from process_line() while +@@ -624,8 +712,6 @@ static int parse_config_file(struct instance_data *idata) + char *line; + int retval; + size_t len = 0; +- glob_t globbuf; +- const char *oldlocale; + size_t n; + + /* +@@ -664,13 +750,16 @@ static int parse_config_file(struct instance_data *idata) + * process_line to process each line. + */ + +- memset(&globbuf, '\0', sizeof(globbuf)); +- oldlocale = setlocale(LC_COLLATE, "C"); +- glob(NAMESPACE_D_GLOB, 0, NULL, &globbuf); +- if (oldlocale != NULL) +- setlocale(LC_COLLATE, oldlocale); +- + confname = PAM_NAMESPACE_CONFIG; ++#ifdef VENDOR_PAM_NAMESPACE_CONFIG ++ /* Check whether PAM_NAMESPACE_CONFIG file is available. ++ * If it does not exist, fall back to VENDOR_PAM_NAMESPACE_CONFIG file. */ ++ struct stat buffer; ++ if (stat(confname, &buffer) != 0 && errno == ENOENT) { ++ confname = VENDOR_PAM_NAMESPACE_CONFIG; ++ } ++#endif ++ char **filename_list = read_namespace_dir(idata); + n = 0; + for (;;) { + if (idata->flags & PAMNS_DEBUG) +@@ -680,7 +769,6 @@ static int parse_config_file(struct instance_data *idata) + if (fil == NULL) { + pam_syslog(idata->pamh, LOG_ERR, "Error opening config file %s", + confname); +- globfree(&globbuf); + free(rhome); + free(home); + return PAM_SERVICE_ERR; +@@ -698,7 +786,6 @@ static int parse_config_file(struct instance_data *idata) + "Error processing conf file %s line %s", confname, line); + fclose(fil); + free(line); +- globfree(&globbuf); + free(rhome); + free(home); + return PAM_SERVICE_ERR; +@@ -707,14 +794,18 @@ static int parse_config_file(struct instance_data *idata) + fclose(fil); + free(line); + +- if (n >= globbuf.gl_pathc) ++ if (filename_list == NULL || filename_list[n] == NULL) + break; + +- confname = globbuf.gl_pathv[n]; +- n++; ++ confname = filename_list[n++]; ++ } ++ ++ if (filename_list != NULL) { ++ for (size_t i = 0; filename_list[i] != NULL; i++) ++ free(filename_list[i]); ++ free(filename_list); + } + +- globfree(&globbuf); + free(rhome); + free(home); + +@@ -1250,16 +1341,17 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath, + struct instance_data *idata, int newdir) + { + pid_t rc, pid; +- struct sigaction newsa, oldsa; + int status; + const char *init_script = NAMESPACE_INIT_SCRIPT; + +- memset(&newsa, '\0', sizeof(newsa)); +- newsa.sa_handler = SIG_DFL; +- if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { +- pam_syslog(idata->pamh, LOG_ERR, "Cannot set signal value"); +- return PAM_SESSION_ERR; ++#ifdef VENDOR_NAMESPACE_INIT_SCRIPT ++ /* Check whether NAMESPACE_INIT_SCRIPT file is available. ++ * If it does not exist, fall back to VENDOR_NAMESPACE_INIT_SCRIPT file. */ ++ struct stat buffer; ++ if (stat(init_script, &buffer) != 0 && errno == ENOENT) { ++ init_script = VENDOR_NAMESPACE_INIT_SCRIPT; + } ++#endif + + if ((polyptr->flags & POLYDIR_ISCRIPT) && polyptr->init_script) + init_script = polyptr->init_script; +@@ -1269,9 +1361,17 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath, + if (idata->flags & PAMNS_DEBUG) + pam_syslog(idata->pamh, LOG_ERR, + "Namespace init script not executable"); +- rc = PAM_SESSION_ERR; +- goto out; ++ return PAM_SESSION_ERR; + } else { ++ struct sigaction newsa, oldsa; ++ ++ memset(&newsa, '\0', sizeof(newsa)); ++ newsa.sa_handler = SIG_DFL; ++ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { ++ pam_syslog(idata->pamh, LOG_ERR, "failed to reset SIGCHLD handler"); ++ return PAM_SESSION_ERR; ++ } ++ + pid = fork(); + if (pid == 0) { + static char *envp[] = { NULL }; +@@ -1309,13 +1409,13 @@ static int inst_init(const struct polydir_s *polyptr, const char *ipath, + rc = PAM_SESSION_ERR; + goto out; + } ++ rc = PAM_SUCCESS; ++out: ++ (void) sigaction(SIGCHLD, &oldsa, NULL); ++ return rc; + } + } +- rc = PAM_SUCCESS; +-out: +- (void) sigaction(SIGCHLD, &oldsa, NULL); +- +- return rc; ++ return PAM_SUCCESS; + } + + static int create_polydir(struct polydir_s *polyptr, diff --git a/modules/pam_namespace/pam_namespace.h b/modules/pam_namespace/pam_namespace.h -index b51f2841..169bd59f 100644 +index b51f2841..0b974ea7 100644 --- a/modules/pam_namespace/pam_namespace.h +++ b/modules/pam_namespace/pam_namespace.h -@@ -90,14 +90,10 @@ +@@ -90,15 +90,17 @@ /* * Module defines */ -#ifndef SECURECONF_DIR -#define SECURECONF_DIR "/etc/security/" --#endif -- --#define PAM_NAMESPACE_CONFIG (SECURECONF_DIR "namespace.conf") --#define NAMESPACE_INIT_SCRIPT (SECURECONF_DIR "namespace.init") --#define NAMESPACE_D_DIR (SECURECONF_DIR "namespace.d/") --#define NAMESPACE_D_GLOB (SECURECONF_DIR "namespace.d/*.conf") +#define PAM_NAMESPACE_CONFIG (SCONFIGDIR "/namespace.conf") +#define NAMESPACE_INIT_SCRIPT (SCONFIGDIR "/namespace.init") +#define NAMESPACE_D_DIR (SCONFIGDIR "/namespace.d/") +#define NAMESPACE_D_GLOB (SCONFIGDIR "/namespace.d/*.conf") - ++#ifdef VENDOR_SCONFIGDIR ++#define VENDOR_NAMESPACE_INIT_SCRIPT (VENDOR_SCONFIGDIR "/namespace.init") ++#define VENDOR_PAM_NAMESPACE_CONFIG (VENDOR_SCONFIGDIR "/namespace.conf") ++#define VENDOR_NAMESPACE_D_DIR (VENDOR_SCONFIGDIR "/namespace.d/") ++#define VENDOR_NAMESPACE_D_GLOB (VENDOR_SCONFIGDIR "/namespace.d/*.conf") + #endif + +-#define PAM_NAMESPACE_CONFIG (SECURECONF_DIR "namespace.conf") +-#define NAMESPACE_INIT_SCRIPT (SECURECONF_DIR "namespace.init") +-#define NAMESPACE_D_DIR (SECURECONF_DIR "namespace.d/") +-#define NAMESPACE_D_GLOB (SECURECONF_DIR "namespace.d/*.conf") +- /* module flags */ #define PAMNS_DEBUG 0x00000100 /* Running in debug mode */ + #define PAMNS_SELINUX_ENABLED 0x00000400 /* SELinux is enabled */ +diff --git a/modules/pam_nologin/pam_nologin.c b/modules/pam_nologin/pam_nologin.c +index b7f9bab0..d7f83e0c 100644 +--- a/modules/pam_nologin/pam_nologin.c ++++ b/modules/pam_nologin/pam_nologin.c +@@ -79,7 +79,6 @@ static int perform_check(pam_handle_t *pamh, struct opt_s *opts) + + if (fd >= 0) { + +- char *mtmp=NULL; + int msg_style = PAM_TEXT_INFO; + struct passwd *user_pwd; + struct stat st; +@@ -99,21 +98,25 @@ static int perform_check(pam_handle_t *pamh, struct opt_s *opts) + goto clean_up_fd; + } + +- mtmp = malloc(st.st_size+1); +- if (!mtmp) { +- pam_syslog(pamh, LOG_CRIT, "out of memory"); +- retval = PAM_BUF_ERR; +- goto clean_up_fd; +- } +- +- if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) { +- mtmp[st.st_size] = '\0'; +- (void) pam_prompt (pamh, msg_style, NULL, "%s", mtmp); ++ /* Don't print anything if the message is empty, will only ++ disturb the output with empty lines */ ++ if (st.st_size > 0) { ++ char *mtmp = malloc(st.st_size+1); ++ if (!mtmp) { ++ pam_syslog(pamh, LOG_CRIT, "out of memory"); ++ retval = PAM_BUF_ERR; ++ goto clean_up_fd; ++ } ++ ++ if (pam_modutil_read(fd, mtmp, st.st_size) == st.st_size) { ++ mtmp[st.st_size] = '\0'; ++ (void) pam_prompt (pamh, msg_style, NULL, "%s", mtmp); ++ } ++ else ++ retval = PAM_SYSTEM_ERR; ++ ++ free(mtmp); + } +- else +- retval = PAM_SYSTEM_ERR; +- +- free(mtmp); + + clean_up_fd: + +diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am +index 8a4dbcb2..c29a8e11 100644 +--- a/modules/pam_pwhistory/Makefile.am ++++ b/modules/pam_pwhistory/Makefile.am +@@ -26,12 +27,14 @@ if HAVE_VERSIONING + pam_pwhistory_la_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map + endif + +-noinst_HEADERS = opasswd.h ++noinst_HEADERS = opasswd.h pwhistory_config.h ++ ++dist_secureconf_DATA = pwhistory.conf + + securelib_LTLIBRARIES = pam_pwhistory.la + pam_pwhistory_la_CFLAGS = $(AM_CFLAGS) + pam_pwhistory_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBCRYPT@ @LIBSELINUX@ +-pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c ++pam_pwhistory_la_SOURCES = pam_pwhistory.c opasswd.c pwhistory_config.c + + sbin_PROGRAMS = pwhistory_helper + pwhistory_helper_CFLAGS = $(AM_CFLAGS) -DHELPER_COMPILE=\"pwhistory_helper\" @EXE_CFLAGS@ diff --git a/modules/pam_pwhistory/opasswd.c b/modules/pam_pwhistory/opasswd.c index a6cd3d2a..1d3242ca 100644 --- a/modules/pam_pwhistory/opasswd.c @@ -900,15 +4705,15 @@ index a6cd3d2a..1d3242ca 100644 @@ -74,8 +75,7 @@ #define RANDOM_DEVICE "/dev/urandom" #endif - + -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" -#define TMP_PASSWORDS_FILE OLD_PASSWORDS_FILE".tmpXXXXXX" +#define DEFAULT_OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd" - + #define DEFAULT_BUFLEN 4096 - + @@ -142,7 +142,7 @@ compare_password(const char *newpass, const char *oldpass) - + /* Check, if the new password is already in the opasswd file. */ PAMH_ARG_DECL(int -check_old_pass, const char *user, const char *newpass, int debug) @@ -919,7 +4724,7 @@ index a6cd3d2a..1d3242ca 100644 @@ -156,10 +156,13 @@ check_old_pass, const char *user, const char *newpass, int debug) return PAM_PWHISTORY_RUN_HELPER; #endif - + - if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL) + const char *opasswd_file = + (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE); @@ -931,10 +4736,10 @@ index a6cd3d2a..1d3242ca 100644 + pam_syslog (pamh, LOG_ERR, "Cannot open %s: %m", opasswd_file); return PAM_SUCCESS; } - + @@ -242,9 +245,8 @@ check_old_pass, const char *user, const char *newpass, int debug) } - + PAMH_ARG_DECL(int -save_old_pass, const char *user, int howmany, int debug UNUSED) +save_old_pass, const char *user, int howmany, const char *filename, int debug UNUSED) @@ -946,7 +4751,7 @@ index a6cd3d2a..1d3242ca 100644 @@ -256,6 +258,15 @@ save_old_pass, const char *user, int howmany, int debug UNUSED) struct passwd *pwd; const char *oldpass; - + + /* Define opasswd file and temp file for opasswd */ + const char *opasswd_file = + (filename != NULL ? filename : DEFAULT_OLD_PASSWORDS_FILE); @@ -962,7 +4767,7 @@ index a6cd3d2a..1d3242ca 100644 @@ -285,24 +296,22 @@ save_old_pass, const char *user, int howmany, int debug UNUSED) if (oldpass == NULL || *oldpass == '\0') return PAM_SUCCESS; - + - if ((oldpf = fopen (OLD_PASSWORDS_FILE, "r")) == NULL) + if ((oldpf = fopen (opasswd_file, "r")) == NULL) { @@ -1028,7 +4833,7 @@ index a6cd3d2a..1d3242ca 100644 @@ -550,12 +555,20 @@ save_old_pass, const char *user, int howmany, int debug UNUSED) goto error_opasswd; } - + - unlink (OLD_PASSWORDS_FILE".old"); - if (link (OLD_PASSWORDS_FILE, OLD_PASSWORDS_FILE".old") != 0 && + char opasswd_backup[PATH_MAX]; @@ -1057,74 +4862,39 @@ index 3f257288..19a4062c 100644 @@ -57,10 +57,10 @@ void helper_log_err(int err, const char *format, ...); #endif - + -PAMH_ARG_DECL(int -check_old_pass, const char *user, const char *newpass, int debug); +PAMH_ARG_DECL(int check_old_pass, const char *user, const char *newpass, + const char *filename, int debug); - + -PAMH_ARG_DECL(int -save_old_pass, const char *user, int howmany, int debug); +PAMH_ARG_DECL(int save_old_pass, const char *user, int howmany, + const char *filename, int debug); - + #endif /* __OPASSWD_H__ */ -diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml -index d88115c2..df16a776 100644 ---- a/modules/pam_pwhistory/pam_pwhistory.8.xml -+++ b/modules/pam_pwhistory/pam_pwhistory.8.xml -@@ -36,6 +36,9 @@ - - authtok_type=STRING - -+ -+ file=/path/filename -+ - - - -@@ -137,6 +140,19 @@ - - - -+ -+ -+ -+ -+ -+ -+ Store password history in file /path/filename -+ rather than the default location. The default location is -+ /etc/security/opasswd. -+ -+ -+ -+ - - - -@@ -213,7 +229,7 @@ password required pam_unix.so use_authtok - - /etc/security/opasswd - -- File with password history -+ Default file with password history - - - diff --git a/modules/pam_pwhistory/pam_pwhistory.c b/modules/pam_pwhistory/pam_pwhistory.c -index ce2c21f5..9c1bdd87 100644 +index ce2c21f5..5a7fb811 100644 --- a/modules/pam_pwhistory/pam_pwhistory.c +++ b/modules/pam_pwhistory/pam_pwhistory.c -@@ -69,6 +69,7 @@ struct options_t { - int enforce_for_root; - int remember; - int tries; -+ const char *filename; - }; - typedef struct options_t options_t; - -@@ -104,13 +105,23 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) +@@ -63,14 +63,8 @@ + + #include "opasswd.h" + #include "pam_inline.h" ++#include "pwhistory_config.h" + +-struct options_t { +- int debug; +- int enforce_for_root; +- int remember; +- int tries; +-}; +-typedef struct options_t options_t; + + + static void +@@ -104,13 +98,23 @@ parse_option (pam_handle_t *pamh, const char *argv, options_t *options) options->enforce_for_root = 1; else if (pam_str_skip_icase_prefix(argv, "authtok_type=") != NULL) { /* ignore, for pam_get_authtok */; } @@ -1141,7 +4911,7 @@ index ce2c21f5..9c1bdd87 100644 else pam_syslog (pamh, LOG_ERR, "pam_pwhistory: unknown option: %s", argv); } - + static int run_save_helper(pam_handle_t *pamh, const char *user, - int howmany, int debug) @@ -1149,16 +4919,16 @@ index ce2c21f5..9c1bdd87 100644 { int retval, child; struct sigaction newsa, oldsa; -@@ -123,7 +134,7 @@ run_save_helper(pam_handle_t *pamh, const char *user, +@@ -123,7 +127,7 @@ run_save_helper(pam_handle_t *pamh, const char *user, if (child == 0) { static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; + char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL, NULL }; - + if (pam_modutil_sanitize_helper_fds(pamh, PAM_MODUTIL_PIPE_FD, PAM_MODUTIL_PIPE_FD, -@@ -137,9 +148,10 @@ run_save_helper(pam_handle_t *pamh, const char *user, +@@ -137,9 +141,10 @@ run_save_helper(pam_handle_t *pamh, const char *user, args[0] = (char *)PWHISTORY_HELPER; args[1] = (char *)"save"; args[2] = (char *)user; @@ -1171,8 +4941,8 @@ index ce2c21f5..9c1bdd87 100644 { pam_syslog(pamh, LOG_ERR, "asprintf: %m"); _exit(PAM_SYSTEM_ERR); -@@ -185,7 +197,7 @@ run_save_helper(pam_handle_t *pamh, const char *user, - +@@ -185,7 +190,7 @@ run_save_helper(pam_handle_t *pamh, const char *user, + static int run_check_helper(pam_handle_t *pamh, const char *user, - const char *newpass, int debug) @@ -1180,16 +4950,16 @@ index ce2c21f5..9c1bdd87 100644 { int retval, child, fds[2]; struct sigaction newsa, oldsa; -@@ -202,7 +214,7 @@ run_check_helper(pam_handle_t *pamh, const char *user, +@@ -202,7 +207,7 @@ run_check_helper(pam_handle_t *pamh, const char *user, if (child == 0) { static char *envp[] = { NULL }; - char *args[] = { NULL, NULL, NULL, NULL, NULL }; + char *args[] = { NULL, NULL, NULL, NULL, NULL, NULL }; - + /* reopen stdin as pipe */ if (dup2(fds[0], STDIN_FILENO) != STDIN_FILENO) -@@ -223,8 +235,9 @@ run_check_helper(pam_handle_t *pamh, const char *user, +@@ -223,8 +228,9 @@ run_check_helper(pam_handle_t *pamh, const char *user, args[0] = (char *)PWHISTORY_HELPER; args[1] = (char *)"check"; args[2] = (char *)user; @@ -1200,38 +4970,263 @@ index ce2c21f5..9c1bdd87 100644 { pam_syslog(pamh, LOG_ERR, "asprintf: %m"); _exit(PAM_SYSTEM_ERR); -@@ -323,10 +336,10 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) +@@ -299,6 +305,8 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) + options.remember = 10; + options.tries = 1; + ++ parse_config_file(pamh, argc, argv, &options); ++ + /* Parse parameters for module */ + for ( ; argc-- > 0; argv++) + parse_option (pamh, *argv, &options); +@@ -306,7 +314,6 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) + if (options.debug) + pam_syslog (pamh, LOG_DEBUG, "pam_sm_chauthtok entered"); + +- + if (options.remember == 0) + return PAM_IGNORE; + +@@ -323,10 +330,10 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) return PAM_SUCCESS; } - + - retval = save_old_pass (pamh, user, options.remember, options.debug); + retval = save_old_pass (pamh, user, options.remember, options.filename, options.debug); - + if (retval == PAM_PWHISTORY_RUN_HELPER) - retval = run_save_helper(pamh, user, options.remember, options.debug); + retval = run_save_helper(pamh, user, options.remember, options.filename, options.debug); - + if (retval != PAM_SUCCESS) return retval; -@@ -358,9 +371,9 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) +@@ -358,9 +365,9 @@ pam_sm_chauthtok (pam_handle_t *pamh, int flags, int argc, const char **argv) if (options.debug) pam_syslog (pamh, LOG_DEBUG, "check against old password file"); - + - retval = check_old_pass (pamh, user, newpass, options.debug); + retval = check_old_pass (pamh, user, newpass, options.filename, options.debug); if (retval == PAM_PWHISTORY_RUN_HELPER) - retval = run_check_helper(pamh, user, newpass, options.debug); + retval = run_check_helper(pamh, user, newpass, options.filename, options.debug); - + if (retval != PAM_SUCCESS) { +diff --git a/modules/pam_pwhistory/pwhistory.conf b/modules/pam_pwhistory/pwhistory.conf +new file mode 100644 +index 00000000..070b7197 +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory.conf +@@ -0,0 +1,21 @@ ++# Configuration for remembering the last passwords used by a user. ++# ++# Enable the debugging logs. ++# Enabled if option is present. ++# debug ++# ++# root account's passwords are also remembered. ++# Enabled if option is present. ++# enforce_for_root ++# ++# Number of passwords to remember. ++# The default is 10. ++# remember = 10 ++# ++# Number of times to prompt for the password. ++# The default is 1. ++# retry = 1 ++# ++# The directory where the last passwords are kept. ++# The default is /etc/security/opasswd. ++# file = /etc/security/opasswd +diff --git a/modules/pam_pwhistory/pwhistory_config.c b/modules/pam_pwhistory/pwhistory_config.c +new file mode 100644 +index 00000000..b21879c6 +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory_config.c +@@ -0,0 +1,115 @@ ++/* ++ * Copyright (c) 2022 Iker Pedrosa ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * the GNU Public License, in which case the provisions of the GPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the GPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++#include ++ ++#include ++ ++#include "pam_inline.h" ++#include "pwhistory_config.h" ++ ++#define PWHISTORY_DEFAULT_CONF SCONFIGDIR "/pwhistory.conf" ++ ++void ++parse_config_file(pam_handle_t *pamh, int argc, const char **argv, ++ struct options_t *options) ++{ ++ const char *fname = NULL; ++ int i; ++ char *val; ++ ++ for (i = 0; i < argc; ++i) { ++ const char *str = pam_str_skip_prefix(argv[i], "conf="); ++ ++ if (str != NULL) { ++ fname = str; ++ } ++ } ++ ++ if (fname == NULL) { ++ fname = PWHISTORY_DEFAULT_CONF; ++ } ++ ++ val = pam_modutil_search_key (pamh, fname, "debug"); ++ if (val != NULL) { ++ options->debug = 1; ++ free(val); ++ } ++ ++ val = pam_modutil_search_key (pamh, fname, "enforce_for_root"); ++ if (val != NULL) { ++ options->enforce_for_root = 1; ++ free(val); ++ } ++ ++ val = pam_modutil_search_key (pamh, fname, "remember"); ++ if (val != NULL) { ++ unsigned int temp; ++ if (sscanf(val, "%u", &temp) != 1) { ++ pam_syslog(pamh, LOG_ERR, ++ "Bad number supplied for remember argument"); ++ } else { ++ options->remember = temp; ++ } ++ free(val); ++ } ++ ++ val = pam_modutil_search_key (pamh, fname, "retry"); ++ if (val != NULL) { ++ unsigned int temp; ++ if (sscanf(val, "%u", &temp) != 1) { ++ pam_syslog(pamh, LOG_ERR, ++ "Bad number supplied for retry argument"); ++ } else { ++ options->tries = temp; ++ } ++ free(val); ++ } ++ ++ val = pam_modutil_search_key (pamh, fname, "file"); ++ if (val != NULL) { ++ if (*val != '/') { ++ pam_syslog (pamh, LOG_ERR, ++ "File path should be absolute: %s", val); ++ } else { ++ options->filename = val; ++ } ++ } ++} +diff --git a/modules/pam_pwhistory/pwhistory_config.h b/modules/pam_pwhistory/pwhistory_config.h +new file mode 100644 +index 00000000..e2b3bc83 +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory_config.h +@@ -0,0 +1,54 @@ ++/* ++ * Copyright (c) 2022 Iker Pedrosa ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, and the entire permission notice in its entirety, ++ * including the disclaimer of warranties. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. The name of the author may not be used to endorse or promote ++ * products derived from this software without specific prior ++ * written permission. ++ * ++ * ALTERNATIVELY, this product may be distributed under the terms of ++ * the GNU Public License, in which case the provisions of the GPL are ++ * required INSTEAD OF the above restrictions. (This clause is ++ * necessary due to a potential bad interaction between the GPL and ++ * the restrictions contained in a BSD-style copyright.) ++ * ++ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED ++ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ++ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE ++ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, ++ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ++ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR ++ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, ++ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ++ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED ++ * OF THE POSSIBILITY OF SUCH DAMAGE. ++ */ ++ ++#ifndef _PWHISTORY_CONFIG_H ++#define _PWHISTORY_CONFIG_H ++ ++#include ++ ++struct options_t { ++ int debug; ++ int enforce_for_root; ++ int remember; ++ int tries; ++ const char *filename; ++}; ++typedef struct options_t options_t; ++ ++void ++parse_config_file(pam_handle_t *pamh, int argc, const char **argv, ++ struct options_t *options); ++ ++#endif /* _PWHISTORY_CONFIG_H */ diff --git a/modules/pam_pwhistory/pwhistory_helper.c b/modules/pam_pwhistory/pwhistory_helper.c index b08a14a7..7a61ae53 100644 --- a/modules/pam_pwhistory/pwhistory_helper.c +++ b/modules/pam_pwhistory/pwhistory_helper.c @@ -51,7 +51,7 @@ - - + + static int -check_history(const char *user, const char *debug) +check_history(const char *user, const char *filename, const char *debug) @@ -1241,15 +5236,15 @@ index b08a14a7..7a61ae53 100644 @@ -68,7 +68,7 @@ check_history(const char *user, const char *debug) return PAM_AUTHTOK_ERR; } - + - retval = check_old_pass(user, pass, dbg); + retval = check_old_pass(user, pass, filename, dbg); - + memset(pass, '\0', PAM_MAX_RESP_SIZE); /* clear memory of the password */ - + @@ -76,13 +76,13 @@ check_history(const char *user, const char *debug) } - + static int -save_history(const char *user, const char *howmany, const char *debug) +save_history(const char *user, const char *filename, const char *howmany, const char *debug) @@ -1257,10 +5252,10 @@ index b08a14a7..7a61ae53 100644 int num = atoi(howmany); int dbg = atoi(debug); /* no need to be too fancy here */ int retval; - + - retval = save_old_pass(user, num, dbg); + retval = save_old_pass(user, num, filename, dbg); - + return retval; } @@ -92,13 +92,14 @@ main(int argc, char *argv[]) @@ -1268,23 +5263,23 @@ index b08a14a7..7a61ae53 100644 const char *option; const char *user; + const char *filename; - + /* * we establish that this program is running with non-tty stdin. * this is to discourage casual use. */ - + - if (isatty(STDIN_FILENO) || argc < 4) + if (isatty(STDIN_FILENO) || argc < 5) { fprintf(stderr, "This binary is not designed for running in this way.\n"); @@ -107,11 +108,12 @@ main(int argc, char *argv[]) - + option = argv[1]; user = argv[2]; + filename = argv[3]; - + - if (strcmp(option, "check") == 0 && argc == 4) - return check_history(user, argv[3]); - else if (strcmp(option, "save") == 0 && argc == 5) @@ -1293,9 +5288,9 @@ index b08a14a7..7a61ae53 100644 + return check_history(user, filename, argv[4]); + else if (strcmp(option, "save") == 0 && argc == 6) + return save_history(user, filename, argv[4], argv[5]); - + fprintf(stderr, "This binary is not designed for running in this way.\n"); - + diff --git a/modules/pam_rootok/pam_rootok.c b/modules/pam_rootok/pam_rootok.c index dd374c53..9bc15abf 100644 --- a/modules/pam_rootok/pam_rootok.c @@ -1306,11 +5301,11 @@ index dd374c53..9bc15abf 100644 { - int audit_fd; va_list ap; - + #ifdef HAVE_LIBAUDIT - audit_fd = audit_open(); + int audit_fd = audit_open(); - + if (audit_fd >= 0) { char *buf; diff --git a/modules/pam_sepermit/Makefile.am b/modules/pam_sepermit/Makefile.am @@ -1323,27 +5318,27 @@ index 18a89b60..bed3b149 100644 dist_check_SCRIPTS = tst-pam_sepermit -TESTS = $(dist_check_SCRIPTS) +TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) - + securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) @@ -21,7 +21,6 @@ sepermitlockdir = ${localstatedir}/run/sepermit - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ -I$(top_srcdir)/libpam_misc/include \ - -D SEPERMIT_CONF_FILE=\"$(SCONFIGDIR)/sepermit.conf\" \ -D SEPERMIT_LOCKDIR=\"$(sepermitlockdir)\" $(WARN_CFLAGS) - + pam_sepermit_la_LIBADD = $(top_builddir)/libpam/libpam.la @LIBSELINUX@ @@ -33,6 +32,9 @@ endif dist_secureconf_DATA = sepermit.conf securelib_LTLIBRARIES = pam_sepermit.la - + +check_PROGRAMS = tst-pam_sepermit-retval +tst_pam_sepermit_retval_LDADD = $(top_builddir)/libpam/libpam.la + install-data-local: mkdir -p $(DESTDIR)$(sepermitlockdir) - + diff --git a/modules/pam_sepermit/pam_sepermit.8.xml b/modules/pam_sepermit/pam_sepermit.8.xml index 30d9cc54..5763c346 100644 --- a/modules/pam_sepermit/pam_sepermit.8.xml @@ -1359,16 +5354,16 @@ index 30d9cc54..5763c346 100644 + %vendordir%/security/sepermit.conf is used. + - + diff --git a/modules/pam_sepermit/pam_sepermit.c b/modules/pam_sepermit/pam_sepermit.c index f7d98d5b..5fbc8fdd 100644 --- a/modules/pam_sepermit/pam_sepermit.c +++ b/modules/pam_sepermit/pam_sepermit.c @@ -61,6 +61,12 @@ - + #include - + +#include "pam_inline.h" + +#define SEPERMIT_CONF_FILE (SCONFIGDIR "/sepermit.conf") @@ -1377,14 +5372,14 @@ index f7d98d5b..5fbc8fdd 100644 +#endif #define MODULE "pam_sepermit" #define OPT_DELIM ":" - + @@ -370,16 +376,31 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, const char *user = NULL; char *seuser = NULL; char *level = NULL; - const char *cfgfile = SEPERMIT_CONF_FILE; + const char *cfgfile = NULL; - + /* Parse arguments. */ for (i = 0; i < argc; i++) { + const char *str; @@ -1412,7 +5407,7 @@ index f7d98d5b..5fbc8fdd 100644 + cfgfile = SEPERMIT_CONF_FILE; +#endif } - + if (debug) diff --git a/modules/pam_sepermit/tst-pam_sepermit-retval.c b/modules/pam_sepermit/tst-pam_sepermit-retval.c new file mode 100644 @@ -1579,42 +5574,221 @@ index 00000000..321bd6d1 + return 0; +} diff --git a/modules/pam_time/Makefile.am b/modules/pam_time/Makefile.am -index 833d51a6..f34f8dce 100644 +index 833d51a6..ad53f1cc 100644 --- a/modules/pam_time/Makefile.am +++ b/modules/pam_time/Makefile.am -@@ -18,7 +18,7 @@ securelibdir = $(SECUREDIR) +@@ -12,13 +12,13 @@ dist_man_MANS = time.conf.5 pam_time.8 + endif + XMLS = README.xml time.conf.5.xml pam_time.8.xml + dist_check_SCRIPTS = tst-pam_time +-TESTS = $(dist_check_SCRIPTS) ++TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) + + securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) - + AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ - -DPAM_TIME_CONF=\"$(SCONFIGDIR)/time.conf\" $(WARN_CFLAGS) + $(WARN_CFLAGS) AM_LDFLAGS = -no-undefined -avoid-version -module if HAVE_VERSIONING AM_LDFLAGS += -Wl,--version-script=$(srcdir)/../modules.map +@@ -28,6 +28,9 @@ pam_time_la_LIBADD = $(top_builddir)/libpam/libpam.la + securelib_LTLIBRARIES = pam_time.la + dist_secureconf_DATA = time.conf + ++check_PROGRAMS = tst-pam_time-retval ++tst_pam_time_retval_LDADD = $(top_builddir)/libpam/libpam.la ++ + if ENABLE_REGENERATE_MAN + dist_noinst_DATA = README + -include $(top_srcdir)/Make.xml.rules +diff --git a/modules/pam_time/pam_time.8.xml b/modules/pam_time/pam_time.8.xml +index 4708220c..a33744ea 100644 +--- a/modules/pam_time/pam_time.8.xml ++++ b/modules/pam_time/pam_time.8.xml +@@ -51,6 +51,11 @@ + /etc/security/time.conf. + An alternative file can be specified with the conffile option. + ++ ++ If there is no explicitly specified configuration file and ++ /etc/security/time.conf does not exist, ++ %vendordir%/security/time.conf is used. ++ + + If Linux PAM is compiled with audit support the module will report + when it denies access. diff --git a/modules/pam_time/pam_time.c b/modules/pam_time/pam_time.c -index 089ae22d..8eebc914 100644 +index 089ae22d..9092597a 100644 --- a/modules/pam_time/pam_time.c +++ b/modules/pam_time/pam_time.c -@@ -33,6 +33,8 @@ +@@ -33,6 +33,11 @@ #include #endif - + +#define PAM_TIME_CONF (SCONFIGDIR "/time.conf") ++#ifdef VENDOR_SCONFIGDIR ++#define VENDOR_PAM_TIME_CONF (VENDOR_SCONFIGDIR "/time.conf") ++#endif + #define PAM_TIME_BUFLEN 1000 #define FIELD_SEPARATOR ';' /* this is new as of .02 */ - + +@@ -53,7 +58,7 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, const char ** + { + int ctrl = 0; + +- *conffile = PAM_TIME_CONF; ++ *conffile = NULL; + /* step through arguments */ + for (; argc-- > 0; ++argv) { + const char *str; +@@ -77,6 +82,20 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, const char ** + } + } + ++ if (*conffile == NULL) { ++ *conffile = PAM_TIME_CONF; ++#ifdef VENDOR_PAM_TIME_CONF ++ /* ++ * Check whether PAM_TIME_CONF file is available. ++ * If it does not exist, fall back to VENDOR_PAM_TIME_CONF file. ++ */ ++ struct stat buffer; ++ if (stat(*conffile, &buffer) != 0 && errno == ENOENT) { ++ *conffile = VENDOR_PAM_TIME_CONF; ++ } ++#endif ++ } ++ + return ctrl; + } + +diff --git a/modules/pam_time/tst-pam_time-retval.c b/modules/pam_time/tst-pam_time-retval.c +new file mode 100644 +index 00000000..281ac80d +--- /dev/null ++++ b/modules/pam_time/tst-pam_time-retval.c +@@ -0,0 +1,107 @@ ++/* ++ * Check pam_time return values. ++ * ++ * Copyright (c) 2020-2022 Dmitry V. Levin ++ * Copyright (c) 2022 Stefan Schubert ++ */ ++ ++#include "test_assert.h" ++ ++#include ++#include ++#include ++#include ++#include ++ ++#define MODULE_NAME "pam_time" ++#define TEST_NAME "tst-" MODULE_NAME "-retval" ++ ++static const char service_file[] = TEST_NAME ".service"; ++static const char config_file[] = TEST_NAME ".conf"; ++static struct pam_conv conv; ++ ++int ++main(void) ++{ ++ pam_handle_t *pamh = NULL; ++ FILE *fp; ++ char cwd[PATH_MAX]; ++ ++ ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd))); ++ ++ /* PAM_USER_UNKNOWN */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, ++ fprintf(fp, "#%%PAM-1.0\n" ++ "auth required %s/.libs/%s.so\n" ++ "account required %s/.libs/%s.so\n" ++ "password required %s/.libs/%s.so\n" ++ "session required %s/.libs/%s.so\n", ++ cwd, MODULE_NAME, ++ cwd, MODULE_NAME, ++ cwd, MODULE_NAME, ++ cwd, MODULE_NAME)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0)); ++ ASSERT_EQ(PAM_USER_UNKNOWN, pam_acct_mgmt(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++ pamh = NULL; ++ ++ ASSERT_NE(NULL, fp = fopen(config_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "# only root can access %s\n" ++ "%s ; * ; !root ; !Al0000-2400\n", ++ service_file, service_file)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ /* conffile= specifies an existing file */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, ++ fprintf(fp, "#%%PAM-1.0\n" ++ "auth required %s/.libs/%s.so conffile=%s\n" ++ "account required %s/.libs/%s.so conffile=%s\n" ++ "password required %s/.libs/%s.so conffile=%s\n" ++ "session required %s/.libs/%s.so conffile=%s\n", ++ cwd, MODULE_NAME, config_file, ++ cwd, MODULE_NAME, config_file, ++ cwd, MODULE_NAME, config_file, ++ cwd, MODULE_NAME, config_file)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "root", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_acct_mgmt(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++ pamh = NULL; ++ ++ ASSERT_EQ(PAM_SUCCESS, ++ pam_start_confdir(service_file, "noone", &conv, ".", &pamh)); ++ ASSERT_NE(NULL, pamh); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_authenticate(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_setcred(pamh, 0)); ++ ASSERT_EQ(PAM_PERM_DENIED, pam_acct_mgmt(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_chauthtok(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_open_session(pamh, 0)); ++ ASSERT_EQ(PAM_MODULE_UNKNOWN, pam_close_session(pamh, 0)); ++ ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); ++ pamh = NULL; ++ ++ /* cleanup */ ++ ASSERT_EQ(0, unlink(config_file)); ++ ASSERT_EQ(0, unlink(service_file)); ++ ++ return 0; ++} diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c index f2474a5b..c8ab49f3 100644 --- a/modules/pam_unix/passverify.c +++ b/modules/pam_unix/passverify.c @@ -334,7 +334,7 @@ PAMH_ARG_DECL(int check_shadow_expiry, - + #define PW_TMPFILE "/etc/npasswd" #define SH_TMPFILE "/etc/nshadow" -#define OPW_TMPFILE "/etc/security/nopasswd" +#define OPW_TMPFILE SCONFIGDIR "/nopasswd" - + /* * i64c - convert an integer to a radix 64 character diff --git a/modules/pam_unix/passverify.h b/modules/pam_unix/passverify.h @@ -1622,20 +5796,135 @@ index c07037d2..463ef185 100644 --- a/modules/pam_unix/passverify.h +++ b/modules/pam_unix/passverify.h @@ -8,7 +8,7 @@ - + #define PAM_UNIX_RUN_HELPER PAM_CRED_INSUFFICIENT - + -#define OLD_PASSWORDS_FILE "/etc/security/opasswd" +#define OLD_PASSWORDS_FILE SCONFIGDIR "/opasswd" - + int is_pwd_shadowed(const struct passwd *pwd); +diff --git a/modules/pam_usertype/pam_usertype.8.xml b/modules/pam_usertype/pam_usertype.8.xml +index 7651da6e..d9307ba3 100644 +--- a/modules/pam_usertype/pam_usertype.8.xml ++++ b/modules/pam_usertype/pam_usertype.8.xml +@@ -31,7 +31,7 @@ + pam_usertype.so is designed to succeed or fail authentication + based on type of the account of the authenticated user. + The type of the account is decided with help of +- SYS_UID_MIN and SYS_UID_MAX ++ SYS_UID_MAX + settings in /etc/login.defs. One use is to select + whether to load other modules based on this test. + +diff --git a/modules/pam_usertype/pam_usertype.c b/modules/pam_usertype/pam_usertype.c +index d03b73b5..cfd9c8bb 100644 +--- a/modules/pam_usertype/pam_usertype.c ++++ b/modules/pam_usertype/pam_usertype.c +@@ -194,7 +194,6 @@ static int + pam_usertype_is_system(pam_handle_t *pamh, uid_t uid) + { + uid_t uid_min; +- uid_t sys_min; + uid_t sys_max; + + if (uid == (uid_t)-1) { +@@ -202,21 +201,19 @@ pam_usertype_is_system(pam_handle_t *pamh, uid_t uid) + return PAM_USER_UNKNOWN; + } + +- if (uid <= 99) { +- /* Reserved. */ +- return PAM_SUCCESS; +- } +- + if (uid == PAM_USERTYPE_OVERFLOW_UID) { + /* nobody */ + return PAM_SUCCESS; + } + + uid_min = pam_usertype_get_id(pamh, "UID_MIN", PAM_USERTYPE_UIDMIN); +- sys_min = pam_usertype_get_id(pamh, "SYS_UID_MIN", PAM_USERTYPE_SYSUIDMIN); + sys_max = pam_usertype_get_id(pamh, "SYS_UID_MAX", uid_min - 1); + +- return uid >= sys_min && uid <= sys_max ? PAM_SUCCESS : PAM_AUTH_ERR; ++ if (uid <= sys_max && uid < uid_min) { ++ return PAM_SUCCESS; ++ } ++ ++ return PAM_AUTH_ERR; + } + + static int +@@ -253,7 +250,7 @@ pam_usertype_evaluate(struct pam_usertype_opts *opts, + + /** + * Arguments: +- * - issystem: uid in ++ * - issystem: uid less than SYS_UID_MAX + * - isregular: not issystem + * - use_uid: use user that runs application not that is being authenticate (same as in pam_succeed_if) + * - audit: log unknown users to syslog +diff --git a/modules/pam_xauth/pam_xauth.c b/modules/pam_xauth/pam_xauth.c +index 03f8dc78..bbb7743b 100644 +--- a/modules/pam_xauth/pam_xauth.c ++++ b/modules/pam_xauth/pam_xauth.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + + #include + #include +@@ -99,6 +100,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, + char *buffer = NULL; + size_t buffer_size = 0; + va_list ap; ++ struct sigaction newsa, oldsa; + + *output = NULL; + +@@ -114,6 +116,17 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, + return -1; + } + ++ memset(&newsa, '\0', sizeof(newsa)); ++ newsa.sa_handler = SIG_DFL; ++ if (sigaction(SIGCHLD, &newsa, &oldsa) == -1) { ++ pam_syslog(pamh, LOG_ERR, "failed to reset SIGCHLD handler: %m"); ++ close(ipipe[0]); ++ close(ipipe[1]); ++ close(opipe[0]); ++ close(opipe[1]); ++ return -1; ++ } ++ + /* Fork off a child. */ + child = fork(); + if (child == -1) { +@@ -209,6 +222,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, + } + close(opipe[0]); + waitpid(child, NULL, 0); ++ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ + return -1; + } + /* Save the new buffer location, copy the newly-read data into +@@ -225,6 +239,7 @@ run_coprocess(pam_handle_t *pamh, const char *input, char **output, + close(opipe[0]); + *output = buffer; + waitpid(child, NULL, 0); ++ sigaction(SIGCHLD, &oldsa, NULL); /* restore old signal handler */ + return 0; + } + diff --git a/xtests/run-xtests.sh b/xtests/run-xtests.sh index 14f585d9..ff9a4dc1 100755 --- a/xtests/run-xtests.sh +++ b/xtests/run-xtests.sh @@ -18,10 +18,12 @@ all=0 - + mkdir -p /etc/security for config in access.conf group.conf time.conf limits.conf ; do - cp /etc/security/$config /etc/security/$config-pam-xtests @@ -1646,7 +5935,7 @@ index 14f585d9..ff9a4dc1 100755 -mv /etc/security/opasswd /etc/security/opasswd-pam-xtests +[ -f /etc/security/opasswd ] && + mv /etc/security/opasswd /etc/security/opasswd-pam-xtests - + for testname in $XTESTS ; do for cfg in "${SRCDIR}"/$testname*.pamd ; do @@ -47,11 +49,15 @@ for testname in $XTESTS ; do @@ -1670,3 +5959,56 @@ index 14f585d9..ff9a4dc1 100755 if test "$failed" -ne 0; then echo "===================" echo "$failed of $all tests failed" +--- /dev/null 2022-12-04 11:36:15.304093045 +0100 ++++ a/doc/man/pam.conf.5.xml 2022-12-06 17:06:03.623994042 +0100 +@@ -0,0 +1,50 @@ ++ ++ ++ ++ ++ ++ pam.conf ++ 5 ++ Linux-PAM Manual ++ ++ ++ ++ pam.conf ++ pam.d ++ PAM configuration files ++ ++ ++ ++ ++ ++ DESCRIPTION ++ ++ ++ ++ ++ ++ ++ ++ ++ SEE ALSO ++ ++ ++ pam3 ++ , ++ ++ PAM8 ++ , ++ ++ pam_start3 ++ ++ ++ ++ ++ diff --git a/pam-hostnames-in-access_conf.patch b/pam-hostnames-in-access_conf.patch deleted file mode 100644 index 076ff17..0000000 --- a/pam-hostnames-in-access_conf.patch +++ /dev/null @@ -1,194 +0,0 @@ -From d275f22cf28da287e93b5e5a1fdb8a68b2815982 Mon Sep 17 00:00:00 2001 -From: Thorsten Kukuk -Date: Thu, 24 Feb 2022 10:37:32 +0100 -Subject: [PATCH] pam_access: handle hostnames in access.conf - -According to the manual page, the following entry is valid but does not -work: --:root:ALL EXCEPT localhost - -See https://bugzilla.suse.com/show_bug.cgi?id=1019866 - -Patched is based on PR#226 from Josef Moellers ---- - modules/pam_access/pam_access.c | 95 ++++++++++++++++++++++++++------- - 1 file changed, 76 insertions(+), 19 deletions(-) - -diff --git a/modules/pam_access/pam_access.c b/modules/pam_access/pam_access.c -index 0d033aa20..3cec542be 100644 ---- a/modules/pam_access/pam_access.c -+++ b/modules/pam_access/pam_access.c -@@ -640,7 +640,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item) - if ((str_len = strlen(string)) > tok_len - && strcasecmp(tok, string + str_len - tok_len) == 0) - return YES; -- } else if (tok[tok_len - 1] == '.') { -+ } else if (tok[tok_len - 1] == '.') { /* internet network numbers (end with ".") */ - struct addrinfo hint; - - memset (&hint, '\0', sizeof (hint)); -@@ -681,7 +681,7 @@ remote_match (pam_handle_t *pamh, char *tok, struct login_info *item) - return NO; - } - -- /* Assume network/netmask with an IP of a host. */ -+ /* Assume network/netmask, IP address or hostname. */ - return network_netmask_match(pamh, tok, string, item); - } - -@@ -699,7 +699,7 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, - /* - * If the token has the magic value "ALL" the match always succeeds. - * Otherwise, return YES if the token fully matches the string. -- * "NONE" token matches NULL string. -+ * "NONE" token matches NULL string. - */ - - if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */ -@@ -717,7 +717,8 @@ string_match (pam_handle_t *pamh, const char *tok, const char *string, - - /* network_netmask_match - match a string against one token - * where string is a hostname or ip (v4,v6) address and tok -- * represents either a single ip (v4,v6) address or a network/netmask -+ * represents either a hostname, a single ip (v4,v6) address -+ * or a network/netmask - */ - static int - network_netmask_match (pam_handle_t *pamh, -@@ -726,10 +727,12 @@ network_netmask_match (pam_handle_t *pamh, - char *netmask_ptr; - char netmask_string[MAXHOSTNAMELEN + 1]; - int addr_type; -+ struct addrinfo *ai = NULL; - - if (item->debug) -- pam_syslog (pamh, LOG_DEBUG, -+ pam_syslog (pamh, LOG_DEBUG, - "network_netmask_match: tok=%s, item=%s", tok, string); -+ - /* OK, check if tok is of type addr/mask */ - if ((netmask_ptr = strchr(tok, '/')) != NULL) - { -@@ -763,54 +766,108 @@ network_netmask_match (pam_handle_t *pamh, - netmask_ptr = number_to_netmask(netmask, addr_type, - netmask_string, MAXHOSTNAMELEN); - } -- } -+ -+ /* -+ * Construct an addrinfo list from the IP address. -+ * This should not fail as the input is a correct IP address... -+ */ -+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0) -+ { -+ return NO; -+ } -+ } - else -- /* NO, then check if it is only an addr */ -- if (isipaddr(tok, NULL, NULL) != YES) -+ { -+ /* -+ * It is either an IP address or a hostname. -+ * Let getaddrinfo sort everything out -+ */ -+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0) - { -+ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok); -+ - return NO; - } -+ netmask_ptr = NULL; -+ } - - if (isipaddr(string, NULL, NULL) != YES) - { -- /* Assume network/netmask with a name of a host. */ - struct addrinfo hint; - -+ /* Assume network/netmask with a name of a host. */ - memset (&hint, '\0', sizeof (hint)); - hint.ai_flags = AI_CANONNAME; - hint.ai_family = AF_UNSPEC; - - if (item->gai_rv != 0) -+ { -+ freeaddrinfo(ai); - return NO; -+ } - else if (!item->res && - (item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0) -+ { -+ freeaddrinfo(ai); - return NO; -+ } - else - { - struct addrinfo *runp = item->res; -+ struct addrinfo *runp1; - - while (runp != NULL) - { - char buf[INET6_ADDRSTRLEN]; - -- DIAG_PUSH_IGNORE_CAST_ALIGN; -- inet_ntop (runp->ai_family, -- runp->ai_family == AF_INET -- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr -- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr, -- buf, sizeof (buf)); -- DIAG_POP_IGNORE_CAST_ALIGN; -+ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0) -+ { -+ freeaddrinfo(ai); -+ return NO; -+ } - -- if (are_addresses_equal(buf, tok, netmask_ptr)) -+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next) - { -- return YES; -+ char buf1[INET6_ADDRSTRLEN]; -+ -+ if (runp->ai_family != runp1->ai_family) -+ continue; -+ -+ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0) -+ { -+ freeaddrinfo(ai); -+ return NO; -+ } -+ -+ if (are_addresses_equal (buf, buf1, netmask_ptr)) -+ { -+ freeaddrinfo(ai); -+ return YES; -+ } - } - runp = runp->ai_next; - } - } - } - else -- return (are_addresses_equal(string, tok, netmask_ptr)); -+ { -+ struct addrinfo *runp1; -+ -+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next) -+ { -+ char buf1[INET6_ADDRSTRLEN]; -+ -+ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST); -+ -+ if (are_addresses_equal(string, buf1, netmask_ptr)) -+ { -+ freeaddrinfo(ai); -+ return YES; -+ } -+ } -+ } -+ -+ freeaddrinfo(ai); - - return NO; - } diff --git a/pam.changes b/pam.changes index db5f842..8f923b1 100644 --- a/pam.changes +++ b/pam.changes @@ -1,3 +1,17 @@ +------------------------------------------------------------------- +Tue Dec 6 16:43:49 UTC 2022 - Thorsten Kukuk + +- pam_pwhistory-docu.patch, docbook5.patch: convert docu to + docbook5 + +------------------------------------------------------------------- +Thu Dec 1 13:51:35 UTC 2022 - Thorsten Kukuk + +- pam-git.diff: update to current git + - obsoletes pam-hostnames-in-access_conf.patch + - obsoletes tst-pam_env-retval.c +- pam_env_econf.patch refresh + ------------------------------------------------------------------- Tue Nov 22 15:24:12 UTC 2022 - Thorsten Kukuk diff --git a/pam.spec b/pam.spec index a09aebc..128d034 100644 --- a/pam.spec +++ b/pam.spec @@ -64,14 +64,14 @@ Source12: pam-login_defs-check.sh Source13: pam.tmpfiles Source14: Linux-PAM-%{version}-docs.tar.xz.asc Source15: Linux-PAM-%{version}.tar.xz.asc -Source16: tst-pam_env-retval.c Patch1: pam-limit-nproc.patch -Patch2: pam-hostnames-in-access_conf.patch Patch3: pam-xauth_ownership.patch Patch4: pam-bsc1177858-dont-free-environment-string.patch Patch10: pam_xauth_data.3.xml.patch Patch11: pam-git.diff Patch12: pam_env_econf.patch +Patch13: pam_pwhistory-docu.patch +Patch14: docbook5.patch BuildRequires: audit-devel BuildRequires: bison BuildRequires: flex @@ -147,7 +147,7 @@ Summary: Manualpages for Pluggable Authentication Modules Group: Documentation/HTML Provides: pam:/%{_mandir}/man8/PAM.8.gz BuildArch: noarch -BuildRequires: docbook-xsl-stylesheets +BuildRequires: docbook5-xsl-stylesheets BuildRequires: elinks BuildRequires: xmlgraphics-fop @@ -177,14 +177,16 @@ building both PAM-aware applications and modules for use with PAM. %prep %setup -q -n Linux-PAM-%{version} -b 1 cp -a %{SOURCE12} . -cp %{SOURCE16} ./modules/pam_env +%patch11 -p1 %patch1 -p1 -%patch2 -p1 %patch3 -p1 %patch4 -p1 %patch10 -p1 -%patch11 -p1 %patch12 -p1 +%if %{build_doc} +%patch13 -p1 +%patch14 -p1 +%endif %build bash ./pam-login_defs-check.sh @@ -343,6 +345,7 @@ done %config(noreplace) %{_pam_secconfdir}/time.conf %config(noreplace) %{_pam_secconfdir}/namespace.conf %config(noreplace) %{_pam_secconfdir}/namespace.init +%config(noreplace) %{_pam_secconfdir}/pwhistory.conf %dir %{_pam_secconfdir}/namespace.d %{_libdir}/libpam.so.0 %{_libdir}/libpam.so.%{libpam_so_version} diff --git a/pam_env_econf.patch b/pam_env_econf.patch index e2db6d9..d79d82d 100644 --- a/pam_env_econf.patch +++ b/pam_env_econf.patch @@ -1,7 +1,38 @@ -diff -Naur org/configure.ac patch/configure.ac ---- org/configure.ac 2022-10-11 12:35:53.558193223 +0200 -+++ patch/configure.ac 2022-10-11 12:36:32.502192985 +0200 -@@ -511,7 +511,11 @@ +From 4b427724082fa2b77cccfa572881c5d2940c754e Mon Sep 17 00:00:00 2001 +From: Stefan Schubert +Date: Fri, 3 Dec 2021 14:33:20 +0100 +Subject: [PATCH] pam_env: Use vendor specific pam_env.conf and environment as + fallback + +Use the vendor directory as fallback for a distribution provided default +config if there is no one in /etc. + +* Makefile.am: Add libeconf setting. +* pam_env.c: Take care about the fallback configuration in the vendor directory. +* tst-pam_env-retval.c: Added tests for libeconf. +* configure.ac: Added ECONF settings for building man pages. +--- + configure.ac | 7 +- + modules/pam_env/.gitignore | 1 + + modules/pam_env/Makefile.am | 4 +- + modules/pam_env/pam_env.c | 298 +++++++++++++++++++++++---- + modules/pam_env/tst-pam_env-retval.c | 60 ++++++ + 7 files changed, 394 insertions(+), 44 deletions(-) + create mode 100644 modules/pam_env/.gitignore + +diff --git a/configure.ac b/configure.ac +index 2f74d1b49..51ca0ad25 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -523,6 +523,7 @@ if test "$WITH_ECONF" = "yes" ; then + PKG_CHECK_MODULES([ECONF], [libeconf], [], + [AC_CHECK_LIB([econf],[econf_readDirs],[ECONF_LIBS="-leconf"],[ECONF_LIBS=""])]) + if test -n "$ECONF_LIBS" ; then ++ AC_CHECK_LIB([econf],[econf_errLocation], [], [AC_MSG_ERROR([Please update libeconf])]) + ECONF_CFLAGS="-DUSE_ECONF=1 $ECONF_CFLAGS" + fi + fi +@@ -535,7 +536,11 @@ if test -n "$enable_vendordir"; then [Directory for distribution provided configuration files]) AC_DEFINE_UNQUOTED([VENDOR_SCONFIGDIR], ["$enable_vendordir/security"], [Directory for PAM modules distribution provided configuration files]) @@ -14,17 +45,18 @@ diff -Naur org/configure.ac patch/configure.ac else STRINGPARAM_VENDORDIR="--stringparam profile.condition 'without_vendordir'" fi -diff -Naur org/modules/pam_env/Makefile.am patch/modules/pam_env/Makefile.am ---- org/modules/pam_env/Makefile.am 2022-10-11 12:35:53.574193223 +0200 -+++ patch/modules/pam_env/Makefile.am 2022-10-11 12:36:32.518192985 +0200 -@@ -12,20 +12,23 @@ - endif - XMLS = README.xml pam_env.conf.5.xml pam_env.8.xml - dist_check_SCRIPTS = tst-pam_env --TESTS = $(dist_check_SCRIPTS) -+TESTS = $(dist_check_SCRIPTS) $(check_PROGRAMS) - - securelibdir = $(SECUREDIR) +diff --git a/modules/pam_env/.gitignore b/modules/pam_env/.gitignore +new file mode 100644 +index 000000000..4c5b234b1 +--- /dev/null ++++ b/modules/pam_env/.gitignore +@@ -0,0 +1 @@ ++tst-pam_env-retval +diff --git a/modules/pam_env/Makefile.am b/modules/pam_env/Makefile.am +index 02cd9d375..b99a83ecb 100644 +--- a/modules/pam_env/Makefile.am ++++ b/modules/pam_env/Makefile.am +@@ -18,14 +18,14 @@ securelibdir = $(SECUREDIR) secureconfdir = $(SCONFIGDIR) AM_CFLAGS = -I$(top_srcdir)/libpam/include -I$(top_srcdir)/libpamc/include \ @@ -38,91 +70,13 @@ diff -Naur org/modules/pam_env/Makefile.am patch/modules/pam_env/Makefile.am securelib_LTLIBRARIES = pam_env.la -pam_env_la_LIBADD = $(top_builddir)/libpam/libpam.la +pam_env_la_LIBADD = $(top_builddir)/libpam/libpam.la $(ECONF_LIBS) -+ -+check_PROGRAMS = tst-pam_env-retval -+tst_pam_env_retval_LDADD = $(top_builddir)/libpam/libpam.la - dist_secureconf_DATA = pam_env.conf - dist_sysconf_DATA = environment -diff -Naur org/modules/pam_env/pam_env.8.xml patch/modules/pam_env/pam_env.8.xml ---- org/modules/pam_env/pam_env.8.xml 2022-10-11 12:35:53.574193223 +0200 -+++ patch/modules/pam_env/pam_env.8.xml 2022-10-11 12:36:32.518192985 +0200 -@@ -52,13 +52,55 @@ - variables as well as PAM_ITEMs such as - PAM_RHOST. - -- -+ -+ Rules for (un)setting of variables can be defined in an own config -+ file. The path to this file can be specified with the -+ conffile option. -+ If this file does not exist, the default rules are taken from the -+ config files /etc/security/pam_env.conf and -+ /etc/security/pam_env.conf.d/*.conf. -+ If the file /etc/security/pam_env.conf does not -+ exist, the rules are taken from the files -+ %vendordir%/security/pam_env.conf, -+ %vendordir%/security/pam_env.conf.d/*.conf and -+ /etc/security/pam_env.conf.d/*.conf in that order. -+ -+ -+ By default rules for (un)setting of variables are taken from the -+ config file /etc/security/pam_env.conf. -+ If this file does not exist %vendordir%/security/pam_env.conf is used. -+ An alternate file can be specified with the conffile -+ option, which overrules all other files. -+ -+ - By default rules for (un)setting of variables are taken from the - config file /etc/security/pam_env.conf. An - alternate file can be specified with the conffile - option. - -- -+ -+ Environment variables can be defined in a file with simple KEY=VAL -+ pairs on separate lines. The path to this file can be specified with the -+ envfile option. -+ If this file has not been defined, the settings are read from the -+ files /etc/security/environment and -+ /etc/security/environment.d/*. -+ If the file /etc/environment does not exist, the -+ settings are read from the files %vendordir%/environment, -+ %vendordir%/environment.d/* and -+ /etc/environment.d/* in that order. -+ And last but not least, with the readenv option this mechanism can -+ be completely disabled. -+ -+ -+ Second a file (/etc/environment by default) with simple -+ KEY=VAL pairs on separate lines will be read. -+ If this file does not exist, %vendordir%/etc/environment is used. -+ With the envfile option an alternate file can be specified, -+ which overrules all other files. -+ And with the readenv option this can be completely disabled. -+ -+ - Second a file (/etc/environment by default) with simple - KEY=VAL pairs on separate lines will be read. - With the envfile option an alternate file can be specified. -@@ -224,12 +266,14 @@ - FILES - - -+ /usr/etc/security/pam_env.conf - /etc/security/pam_env.conf - - Default configuration file - - - -+ /usr/etc/environment - /etc/environment - - Default environment file -diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c ---- org/modules/pam_env/pam_env.c 2022-10-11 12:35:53.574193223 +0200 -+++ patch/modules/pam_env/pam_env.c 2022-10-11 12:36:32.518192985 +0200 + check_PROGRAMS = tst-pam_env-retval + tst_pam_env_retval_LDADD = $(top_builddir)/libpam/libpam.la +diff --git a/modules/pam_env/pam_env.c b/modules/pam_env/pam_env.c +index 64a586454..aabab7992 100644 +--- a/modules/pam_env/pam_env.c ++++ b/modules/pam_env/pam_env.c @@ -7,6 +7,9 @@ */ @@ -143,7 +97,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c #include #include -@@ -42,6 +48,9 @@ +@@ -42,6 +48,9 @@ typedef struct var { } VAR; #define DEFAULT_CONF_FILE (SCONFIGDIR "/pam_env.conf") @@ -153,19 +107,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c #define BUF_SIZE 8192 #define MAX_ENV 8192 -@@ -53,18 +62,19 @@ - #define UNDEFINE_VAR 102 - #define ILLEGAL_VAR 103 - --static int _assemble_line(FILE *, char *, int); --static int _parse_line(const pam_handle_t *, const char *, VAR *); --static int _check_var(pam_handle_t *, VAR *); /* This is the real meat */ --static void _clean_var(VAR *); --static int _expand_arg(pam_handle_t *, char **); --static const char * _pam_get_item_byname(pam_handle_t *, const char *); --static int _define_var(pam_handle_t *, int, VAR *); --static int _undefine_var(pam_handle_t *, int, VAR *); -- +@@ -56,6 +65,16 @@ typedef struct var { /* This is a special value used to designate an empty string */ static char quote='\0'; @@ -182,7 +124,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c /* argument parsing */ #define PAM_DEBUG_ARG 0x01 -@@ -77,10 +87,10 @@ +@@ -68,10 +87,10 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, int ctrl=0; *user_envfile = DEFAULT_USER_ENVFILE; @@ -195,31 +137,15 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c /* step through arguments */ for (; argc-- > 0; ++argv) { -@@ -128,166 +138,145 @@ +@@ -119,6 +138,148 @@ _pam_parse (const pam_handle_t *pamh, int argc, const char **argv, return ctrl; } --static int --_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) --{ -- int retval; -- char buffer[BUF_SIZE]; -- FILE *conf; -- VAR Var, *var=&Var; -- -- D(("Called.")); -- -- var->name=NULL; var->defval=NULL; var->override=NULL; +#ifdef USE_ECONF - -- D(("Config file name is: %s", file)); ++ +#define ENVIRONMENT "environment" +#define PAM_ENV "pam_env" - -- /* -- * Lets try to open the config file, parse it and process -- * any variables found. -- */ ++ +static int +isDirectory(const char *path) { + struct stat statbuf; @@ -227,10 +153,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + return 0; + return S_ISDIR(statbuf.st_mode); +} - -- if ((conf = fopen(file,"r")) == NULL) { -- pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file); -- return PAM_IGNORE; ++ +static int +econf_read_file(const pam_handle_t *pamh, const char *filename, const char *delim, + const char *name, const char *suffix, const char *subpath, @@ -260,23 +183,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + return PAM_ABORT; + } + } - } -- -- /* _pam_assemble_line will provide a complete line from the config file, -- * with all comments removed and any escaped newlines fixed up -- */ -- -- while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { -- D(("Read line: %s", buffer)); -- -- if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) { -- retval = _check_var(pamh, var); -- -- if (DEFINE_VAR == retval) { -- retval = _define_var(pamh, ctrl, var); -- -- } else if (UNDEFINE_VAR == retval) { -- retval = _undefine_var(pamh, ctrl, var); ++ } + if (filename == NULL || base_dir[0] != '\0') { + /* Read and merge all setting in e.g. /usr/etc and /etc */ + char *vendor_dir = NULL, *sysconf_dir; @@ -303,95 +210,33 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + pam_syslog(pamh, LOG_ERR, "Cannot allocate memory."); + free(vendor_dir); + return PAM_BUF_ERR; - } - } -- if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval -- && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; -- -- _clean_var(var); -- -- } /* while */ -- -- (void) fclose(conf); -- -- /* tidy up */ -- _clean_var(var); /* We could have got here prematurely, -- * this is safe though */ -- D(("Exit.")); -- return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); --} - --static int --_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) --{ -- int retval=PAM_SUCCESS, i, t; -- char buffer[BUF_SIZE], *key, *mark; -- FILE *conf; -- -- D(("Env file name is: %s", file)); -- -- if ((conf = fopen(file,"r")) == NULL) { -- pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file); -- return PAM_IGNORE; ++ } ++ } ++ + D(("Read configuration from directory %s and %s", vendor_dir, sysconf_dir)); + error = econf_readDirs (&key_file, vendor_dir, sysconf_dir, name, suffix, + delim, "#"); + free(vendor_dir); + free(sysconf_dir); + if (error != ECONF_SUCCESS) { -+ pam_syslog(pamh, LOG_ERR, "Unable to read configuration in different directories: %s", -+ econf_errString(error)); -+ if (error == ECONF_NOFILE) ++ if (error == ECONF_NOFILE) { ++ pam_syslog(pamh, LOG_ERR, "Configuration file not found: %s%s", name, suffix); + return PAM_IGNORE; -+ else ++ } else { ++ char *error_filename = NULL; ++ uint64_t error_line = 0; ++ ++ econf_errLocation(&error_filename, &error_line); ++ pam_syslog(pamh, LOG_ERR, "Unable to read configuration file %s line %ld: %s", ++ error_filename, ++ error_line, ++ econf_errString(error)); ++ free(error_filename); + return PAM_ABORT; ++ } + } - } - -- while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { -- D(("Read line: %s", buffer)); -- key = buffer; -- -- /* skip leading white space */ -- key += strspn(key, " \n\t"); -- -- /* skip blanks lines and comments */ -- if (key[0] == '#') -- continue; -- -- /* skip over "export " if present so we can be compat with -- bash type declarations */ -- if (strncmp(key, "export ", (size_t) 7) == 0) -- key += 7; -- -- /* now find the end of value */ -- mark = key; -- while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') -- mark++; -- if (mark[0] != '\0') -- mark[0] = '\0'; -- -- /* -- * sanity check, the key must be alphanumeric -- */ -- -- if (key[0] == '=') { -- pam_syslog(pamh, LOG_ERR, -- "missing key name '%s' in %s', ignoring", -- key, file); -- continue; -- } -- -- for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) -- if (!isalnum(key[i]) && key[i] != '_') { -- pam_syslog(pamh, LOG_ERR, -- "non-alphanumeric key '%s' in %s', ignoring", -- key, file); -- break; -- } -- /* non-alphanumeric key, ignore this line */ -- if (key[i] != '=' && key[i] != '\0') -- continue; ++ } ++ + error = econf_getKeys(key_file, NULL, &key_number, &keys); + if (error != ECONF_SUCCESS && error != ECONF_NOKEY) { + pam_syslog(pamh, LOG_ERR, "Unable to read keys: %s", @@ -399,18 +244,7 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + econf_freeFile(key_file); + return PAM_ABORT; + } - -- /* now we try to be smart about quotes around the value, -- but not too smart, we can't get all fancy with escaped -- values like bash */ -- if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { -- for ( t = i+1 ; key[t] != '\0' ; t++) -- if (key[t] != '\"' && key[t] != '\'') -- key[i++] = key[t]; -- else if (key[t+1] != '\0') -- key[i++] = key[t]; -- key[i] = '\0'; -- } ++ + *lines = malloc((key_number +1)* sizeof(char**)); + if (*lines == NULL) { + pam_syslog(pamh, LOG_ERR, "Cannot allocate memory."); @@ -418,26 +252,12 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + econf_freeFile(key_file); + return PAM_BUF_ERR; + } - -- /* if this is a request to delete a variable, check that it's -- actually set first, so we don't get a vague error back from -- pam_putenv() */ -- for (i = 0; key[i] != '=' && key[i] != '\0'; i++); ++ + (*lines)[key_number] = 0; - -- if (key[i] == '\0' && !pam_getenv(pamh,key)) -- continue; ++ + for (size_t i = 0; i < key_number; i++) { + char *val; - -- /* set the env var, if it fails, we break out of the loop */ -- retval = pam_putenv(pamh, key); -- if (retval != PAM_SUCCESS) { -- D(("error setting env \"%s\"", key)); -- break; -- } else if (ctrl & PAM_DEBUG_ARG) { -- pam_syslog(pamh, LOG_DEBUG, -- "pam_putenv(\"%s\")", key); ++ + error = econf_getStringValue (key_file, NULL, keys[i], &val); + if (error != ECONF_SUCCESS) { + pam_syslog(pamh, LOG_ERR, "Unable to get string from key %s: %s", @@ -451,35 +271,22 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + free_string_array(*lines); + free (val); + return PAM_BUF_ERR; - } ++ } + free (val); + } - } - -- (void) fclose(conf); -- -- /* tidy up */ -- D(("Exit.")); -- return retval; ++ } ++ + econf_free(keys); + econf_free(key_file); + return PAM_SUCCESS; - } - ++} ++ +#else + /* * This is where we read a line of the PAM config file. The line may be * preceded by lines of comments and also extended with "\\\n" - */ -- --static int _assemble_line(FILE *f, char *buffer, int buf_len) -+static int -+_assemble_line(FILE *f, char *buffer, int buf_len) - { - char *p = buffer; - char *s, *os; -@@ -375,8 +364,54 @@ +@@ -212,6 +373,52 @@ _assemble_line(FILE *f, char *buffer, int buf_len) return used; } @@ -530,294 +337,24 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c +#endif + static int --_parse_line (const pam_handle_t *pamh, const char *buffer, VAR *var) -+_parse_line(const pam_handle_t *pamh, const char *buffer, VAR *var) + _parse_line(const pam_handle_t *pamh, const char *buffer, VAR *var) { - /* - * parse buffer into var, legal syntax is -@@ -471,75 +506,57 @@ - return GOOD_LINE; - } - --static int _check_var(pam_handle_t *pamh, VAR *var) -+static const char * -+_pam_get_item_byname(pam_handle_t *pamh, const char *name) +@@ -626,34 +833,38 @@ static int + _parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) { - /* -- * Examine the variable and determine what action to take. -- * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take -- * or a PAM_* error code if passed back from other routines -- * -- * if no DEFAULT provided, the empty string is assumed -- * if no OVERRIDE provided, the empty string is assumed -- * if DEFAULT= and OVERRIDE evaluates to the empty string, -- * this variable should be undefined -- * if DEFAULT="" and OVERRIDE evaluates to the empty string, -- * this variable should be defined with no value -- * if OVERRIDE=value and value turns into the empty string, DEFAULT is used -- * -- * If DEFINE_VAR is to be returned, the correct value to define will -- * be pointed to by var->value -+ * This function just allows me to use names as given in the config -+ * file and translate them into the appropriate PAM_ITEM macro - */ - -- int retval; -+ int item; -+ const void *itemval; - - D(("Called.")); + int retval; +- char buffer[BUF_SIZE]; +- FILE *conf; + VAR Var, *var=&Var; - -- /* -- * First thing to do is to expand any arguments, but only -- * if they are not the special quote values (cause expand_arg -- * changes memory). -- */ -- -- if (var->defval && ("e != var->defval) && -- ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { -- return retval; -- } -- if (var->override && ("e != var->override) && -- ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { -- return retval; -+ if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) { -+ item = PAM_USER; -+ } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { -+ item = PAM_USER_PROMPT; -+ } else if (strcmp(name, "PAM_TTY") == 0) { -+ item = PAM_TTY; -+ } else if (strcmp(name, "PAM_RUSER") == 0) { -+ item = PAM_RUSER; -+ } else if (strcmp(name, "PAM_RHOST") == 0) { -+ item = PAM_RHOST; -+ } else { -+ D(("Unknown PAM_ITEM: <%s>", name)); -+ pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name); -+ return NULL; - } - -- /* Now its easy */ -- -- if (var->override && *(var->override)) { -- /* if there is a non-empty string in var->override, we use it */ -- D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); -- var->value = var->override; -- retval = DEFINE_VAR; -- } else { -+ if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) { -+ D(("pam_get_item failed")); -+ return NULL; /* let pam_get_item() log the error */ -+ } - -- var->value = var->defval; -- if ("e == var->defval) { -- /* -- * This means that the empty string was given for defval value -- * which indicates that a variable should be defined with no value -- */ -- D(("An empty variable: <%s>", var->name)); -- retval = DEFINE_VAR; -- } else if (var->defval) { -- D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); -- retval = DEFINE_VAR; -- } else { -- D(("UNDEFINE variable <%s>", var->name)); -- retval = UNDEFINE_VAR; -+ if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) { -+ struct passwd *user_entry; -+ user_entry = pam_modutil_getpwnam (pamh, itemval); -+ if (!user_entry) { -+ pam_syslog(pamh, LOG_ERR, "No such user!?"); -+ return NULL; - } -+ return (strcmp(name, "SHELL") == 0) ? -+ user_entry->pw_shell : -+ user_entry->pw_dir; - } - - D(("Exit.")); -- return retval; -+ return itemval; - } - --static int _expand_arg(pam_handle_t *pamh, char **value) -+static int -+_expand_arg(pam_handle_t *pamh, char **value) - { - const char *orig=*value, *tmpptr=NULL; - char *ptr; /* -@@ -679,55 +696,96 @@ - return PAM_SUCCESS; - } - --static const char * _pam_get_item_byname(pam_handle_t *pamh, const char *name) -+static int -+_check_var(pam_handle_t *pamh, VAR *var) - { - /* -- * This function just allows me to use names as given in the config -- * file and translate them into the appropriate PAM_ITEM macro -+ * Examine the variable and determine what action to take. -+ * Returns DEFINE_VAR, UNDEFINE_VAR depending on action to take -+ * or a PAM_* error code if passed back from other routines -+ * -+ * if no DEFAULT provided, the empty string is assumed -+ * if no OVERRIDE provided, the empty string is assumed -+ * if DEFAULT= and OVERRIDE evaluates to the empty string, -+ * this variable should be undefined -+ * if DEFAULT="" and OVERRIDE evaluates to the empty string, -+ * this variable should be defined with no value -+ * if OVERRIDE=value and value turns into the empty string, DEFAULT is used -+ * -+ * If DEFINE_VAR is to be returned, the correct value to define will -+ * be pointed to by var->value - */ - -- int item; -- const void *itemval; -+ int retval; - - D(("Called.")); -- if (strcmp(name, "PAM_USER") == 0 || strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0) { -- item = PAM_USER; -- } else if (strcmp(name, "PAM_USER_PROMPT") == 0) { -- item = PAM_USER_PROMPT; -- } else if (strcmp(name, "PAM_TTY") == 0) { -- item = PAM_TTY; -- } else if (strcmp(name, "PAM_RUSER") == 0) { -- item = PAM_RUSER; -- } else if (strcmp(name, "PAM_RHOST") == 0) { -- item = PAM_RHOST; -- } else { -- D(("Unknown PAM_ITEM: <%s>", name)); -- pam_syslog (pamh, LOG_ERR, "Unknown PAM_ITEM: <%s>", name); -- return NULL; -- } - -- if (pam_get_item(pamh, item, &itemval) != PAM_SUCCESS) { -- D(("pam_get_item failed")); -- return NULL; /* let pam_get_item() log the error */ -+ /* -+ * First thing to do is to expand any arguments, but only -+ * if they are not the special quote values (cause expand_arg -+ * changes memory). -+ */ -+ -+ if (var->defval && ("e != var->defval) && -+ ((retval = _expand_arg(pamh, &(var->defval))) != PAM_SUCCESS)) { -+ return retval; -+ } -+ if (var->override && ("e != var->override) && -+ ((retval = _expand_arg(pamh, &(var->override))) != PAM_SUCCESS)) { -+ return retval; - } - -- if (itemval && (strcmp(name, "HOME") == 0 || strcmp(name, "SHELL") == 0)) { -- struct passwd *user_entry; -- user_entry = pam_modutil_getpwnam (pamh, itemval); -- if (!user_entry) { -- pam_syslog(pamh, LOG_ERR, "No such user!?"); -- return NULL; -+ /* Now its easy */ -+ -+ if (var->override && *(var->override)) { -+ /* if there is a non-empty string in var->override, we use it */ -+ D(("OVERRIDE variable <%s> being used: <%s>", var->name, var->override)); -+ var->value = var->override; -+ retval = DEFINE_VAR; -+ } else { -+ -+ var->value = var->defval; -+ if ("e == var->defval) { -+ /* -+ * This means that the empty string was given for defval value -+ * which indicates that a variable should be defined with no value -+ */ -+ D(("An empty variable: <%s>", var->name)); -+ retval = DEFINE_VAR; -+ } else if (var->defval) { -+ D(("DEFAULT variable <%s> being used: <%s>", var->name, var->defval)); -+ retval = DEFINE_VAR; -+ } else { -+ D(("UNDEFINE variable <%s>", var->name)); -+ retval = UNDEFINE_VAR; - } -- return (strcmp(name, "SHELL") == 0) ? -- user_entry->pw_shell : -- user_entry->pw_dir; - } - - D(("Exit.")); -- return itemval; -+ return retval; - } - --static int _define_var(pam_handle_t *pamh, int ctrl, VAR *var) -+static void -+_clean_var(VAR *var) -+{ -+ if (var->name) { -+ free(var->name); -+ } -+ if (var->defval && ("e != var->defval)) { -+ free(var->defval); -+ } -+ if (var->override && ("e != var->override)) { -+ free(var->override); -+ } -+ var->name = NULL; -+ var->value = NULL; /* never has memory specific to it */ -+ var->defval = NULL; -+ var->override = NULL; -+ return; -+} -+ -+static int -+_define_var(pam_handle_t *pamh, int ctrl, VAR *var) - { - /* We have a variable to define, this is a simple function */ - -@@ -749,7 +807,8 @@ - return retval; - } - --static int _undefine_var(pam_handle_t *pamh, int ctrl, VAR *var) -+static int -+_undefine_var(pam_handle_t *pamh, int ctrl, VAR *var) - { - /* We have a variable to undefine, this is a simple function */ - -@@ -760,25 +819,176 @@ - return pam_putenv(pamh, var->name); - } - --static void _clean_var(VAR *var) -+static int -+_parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) - { -- if (var->name) { -- free(var->name); -- } -- if (var->defval && ("e != var->defval)) { -- free(var->defval); -- } -- if (var->override && ("e != var->override)) { -- free(var->override); -- } -- var->name = NULL; -- var->value = NULL; /* never has memory specific to it */ -- var->defval = NULL; -- var->override = NULL; -- return; -+ int retval; -+ VAR Var, *var=&Var; +- D(("Called.")); + char **conf_list = NULL; -+ -+ var->name=NULL; var->defval=NULL; var->override=NULL; -+ + + var->name=NULL; var->defval=NULL; var->override=NULL; + +- D(("Config file name is: %s", file)); + D(("Called.")); -+ + +#ifdef USE_ECONF + /* If "file" is not NULL, only this file will be parsed. */ + retval = econf_read_file(pamh, file, " \t", PAM_ENV, ".conf", "security", &conf_list); @@ -826,51 +363,66 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + if (file == NULL) /* No filename has been set via argv. */ + file = DEFAULT_CONF_FILE; +#ifdef VENDOR_DEFAULT_CONF_FILE -+ /* + /* +- * Lets try to open the config file, parse it and process +- * any variables found. +- */ +- +- if ((conf = fopen(file,"r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "Unable to open config file: %s: %m", file); +- return PAM_IGNORE; + * Check whether file is available. + * If it does not exist, fall back to VENDOR_DEFAULT_CONF_FILE file. + */ + struct stat stat_buffer; + if (stat(file, &stat_buffer) != 0 && errno == ENOENT) { + file = VENDOR_DEFAULT_CONF_FILE; -+ } + } +#endif + retval = read_file(pamh, file, &conf_list); +#endif -+ + +- /* _pam_assemble_line will provide a complete line from the config file, +- * with all comments removed and any escaped newlines fixed up +- */ +- +- while (( retval = _assemble_line(conf, buffer, BUF_SIZE)) > 0) { +- D(("Read line: %s", buffer)); + if (retval != PAM_SUCCESS) + return retval; -+ + +- if ((retval = _parse_line(pamh, buffer, var)) == GOOD_LINE) { + for (char **conf = conf_list; *conf != NULL; ++conf) { + if ((retval = _parse_line(pamh, *conf, var)) == GOOD_LINE) { -+ retval = _check_var(pamh, var); -+ -+ if (DEFINE_VAR == retval) { -+ retval = _define_var(pamh, ctrl, var); -+ -+ } else if (UNDEFINE_VAR == retval) { -+ retval = _undefine_var(pamh, ctrl, var); -+ } -+ } -+ if (PAM_SUCCESS != retval && ILLEGAL_VAR != retval -+ && BAD_LINE != retval && PAM_BAD_ITEM != retval) break; -+ -+ _clean_var(var); -+ -+ } /* for */ -+ -+ /* tidy up */ -+ free_string_array(conf_list); -+ _clean_var(var); /* We could have got here prematurely, -+ * this is safe though */ -+ D(("Exit.")); -+ return (retval != 0 ? PAM_ABORT : PAM_SUCCESS); - } + retval = _check_var(pamh, var); -+static int -+_parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) -+{ -+ int retval=PAM_SUCCESS, i, t; + if (DEFINE_VAR == retval) { +@@ -668,11 +879,10 @@ _parse_config_file(pam_handle_t *pamh, int ctrl, const char *file) + + _clean_var(var); + +- } /* while */ +- +- (void) fclose(conf); ++ } /* for */ + + /* tidy up */ ++ free_string_array(conf_list); + _clean_var(var); /* We could have got here prematurely, + * this is safe though */ + D(("Exit.")); +@@ -683,19 +893,33 @@ static int + _parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) + { + int retval=PAM_SUCCESS, i, t; +- char buffer[BUF_SIZE], *key, *mark; +- FILE *conf; +- +- D(("Env file name is: %s", file)); +- +- if ((conf = fopen(file,"r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "Unable to open env file: %s: %m", file); +- return PAM_IGNORE; + char *key, *mark; + char **env_list = NULL; + @@ -888,132 +440,137 @@ diff -Naur org/modules/pam_env/pam_env.c patch/modules/pam_env/pam_env.c + struct stat stat_buffer; + if (stat(file, &stat_buffer) != 0 && errno == ENOENT) { + file = VENDOR_DEFAULT_ETC_ENVFILE; -+ } + } +#endif + retval = read_file(pamh, file, &env_list); +#endif -+ + +- while (_assemble_line(conf, buffer, BUF_SIZE) > 0) { +- D(("Read line: %s", buffer)); +- key = buffer; + if (retval != PAM_SUCCESS) + return retval == PAM_IGNORE ? PAM_SUCCESS : retval; + + for (char **env = env_list; *env != NULL; ++env) { + key = *env; -+ -+ /* skip leading white space */ -+ key += strspn(key, " \n\t"); -+ -+ /* skip blanks lines and comments */ -+ if (key[0] == '#') -+ continue; -+ -+ /* skip over "export " if present so we can be compat with -+ bash type declarations */ -+ if (strncmp(key, "export ", (size_t) 7) == 0) -+ key += 7; -+ -+ /* now find the end of value */ -+ mark = key; -+ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0') -+ mark++; -+ if (mark[0] != '\0') -+ mark[0] = '\0'; -+ -+ /* -+ * sanity check, the key must be alphanumeric -+ */ -+ -+ if (key[0] == '=') { -+ pam_syslog(pamh, LOG_ERR, -+ "missing key name '%s' in %s', ignoring", -+ key, file); -+ continue; -+ } -+ -+ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ ) -+ if (!isalnum(key[i]) && key[i] != '_') { -+ pam_syslog(pamh, LOG_ERR, -+ "non-alphanumeric key '%s' in %s', ignoring", -+ key, file); -+ break; -+ } -+ /* non-alphanumeric key, ignore this line */ -+ if (key[i] != '=' && key[i] != '\0') -+ continue; -+ -+ /* now we try to be smart about quotes around the value, -+ but not too smart, we can't get all fancy with escaped -+ values like bash */ -+ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) { -+ for ( t = i+1 ; key[t] != '\0' ; t++) -+ if (key[t] != '\"' && key[t] != '\'') -+ key[i++] = key[t]; -+ else if (key[t+1] != '\0') -+ key[i++] = key[t]; -+ key[i] = '\0'; -+ } -+ -+ /* if this is a request to delete a variable, check that it's -+ actually set first, so we don't get a vague error back from -+ pam_putenv() */ -+ for (i = 0; key[i] != '=' && key[i] != '\0'; i++); -+ -+ if (key[i] == '\0' && !pam_getenv(pamh,key)) -+ continue; -+ -+ /* set the env var, if it fails, we break out of the loop */ -+ retval = pam_putenv(pamh, key); -+ if (retval != PAM_SUCCESS) { -+ D(("error setting env \"%s\"", key)); -+ break; -+ } else if (ctrl & PAM_DEBUG_ARG) { -+ pam_syslog(pamh, LOG_DEBUG, -+ "pam_putenv(\"%s\")", key); -+ } + + /* skip leading white space */ + key += strspn(key, " \n\t"); +@@ -767,11 +991,11 @@ _parse_env_file(pam_handle_t *pamh, int ctrl, const char *file) + pam_syslog(pamh, LOG_DEBUG, + "pam_putenv(\"%s\")", key); + } + free(*env); -+ } + } -+ /* tidy up */ +- (void) fclose(conf); +- + /* tidy up */ + free(env_list); -+ D(("Exit.")); -+ return retval; -+} + D(("Exit.")); + return retval; + } +diff --git a/modules/pam_env/tst-pam_env-retval.c b/modules/pam_env/tst-pam_env-retval.c +index 6b9b3065a..99e2e2a54 100644 +--- a/modules/pam_env/tst-pam_env-retval.c ++++ b/modules/pam_env/tst-pam_env-retval.c +@@ -17,11 +17,18 @@ - /* --- authentication management functions (only) --- */ + #define MODULE_NAME "pam_env" + #define TEST_NAME "tst-" MODULE_NAME "-retval" ++#define TEST_NAME_DIR TEST_NAME ".dir" -diff -Naur org/modules/pam_env/pam_env.conf.5.xml patch/modules/pam_env/pam_env.conf.5.xml ---- org/modules/pam_env/pam_env.conf.5.xml 2022-10-11 12:35:53.574193223 +0200 -+++ patch/modules/pam_env/pam_env.conf.5.xml 2022-10-11 12:36:32.518192985 +0200 -@@ -20,7 +20,15 @@ - - DESCRIPTION + static const char service_file[] = TEST_NAME ".service"; + static const char missing_file[] = TEST_NAME ".missing"; ++static const char dir[] = TEST_NAME_DIR; ++static const char dir_usr[] = TEST_NAME_DIR "/usr"; ++static const char dir_usr_etc[] = TEST_NAME_DIR "/usr/etc"; ++static const char dir_usr_etc_security[] = TEST_NAME_DIR "/usr/etc/security"; + static const char my_conf[] = TEST_NAME ".conf"; + static const char my_env[] = TEST_NAME ".env"; ++static const char usr_env[] = TEST_NAME_DIR "/usr/etc/environment"; ++static const char usr_conf[] = TEST_NAME_DIR "/usr/etc/security/pam_env.conf"; -- -+ -+ The /usr/etc/security/pam_env.conf and -+ /etc/security/pam_env.conf files specify -+ the environment variables to be set, unset or modified by -+ pam_env8. -+ When someone logs in, these files are read and the environment -+ variables are set according. -+ -+ - The /etc/security/pam_env.conf file specifies - the environment variables to be set, unset or modified by - pam_env8. -@@ -61,7 +69,15 @@ - at front) can be used to mark this line as a comment line. - + static struct pam_conv conv; -- -+ -+ The /usr/etc/environment and /etc/environment files specify -+ the environment variables to be set. These files must consist of simple -+ NAME=VALUE pairs on separate lines. -+ The pam_env8 -+ module will read these files after the pam_env.conf -+ file. -+ -+ - The /etc/environment file specifies - the environment variables to be set. The file must consist of simple - NAME=VALUE pairs on separate lines. +@@ -30,6 +37,11 @@ setup(void) + { + FILE *fp; + ++ ASSERT_EQ(0, mkdir(dir, 0755)); ++ ASSERT_EQ(0, mkdir(dir_usr, 0755)); ++ ASSERT_EQ(0, mkdir(dir_usr_etc, 0755)); ++ ASSERT_EQ(0, mkdir(dir_usr_etc_security, 0755)); ++ + ASSERT_NE(NULL, fp = fopen(my_conf, "w")); + ASSERT_LT(0, fprintf(fp, + "EDITOR\tDEFAULT=vim\n" +@@ -41,6 +53,18 @@ setup(void) + "test_value=foo\n" + "test2_value=bar\n")); + ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_NE(NULL, fp = fopen(usr_env, "w")); ++ ASSERT_LT(0, fprintf(fp, ++ "usr_etc_test=foo\n" ++ "usr_etc_test2=bar\n")); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ ASSERT_NE(NULL, fp = fopen(usr_conf, "w")); ++ ASSERT_LT(0, fprintf(fp, ++ "PAGER DEFAULT=emacs\n" ++ "MANPAGER DEFAULT=less\n")); ++ ASSERT_EQ(0, fclose(fp)); + } + + static void +@@ -48,6 +72,12 @@ cleanup(void) + { + ASSERT_EQ(0, unlink(my_conf)); + ASSERT_EQ(0, unlink(my_env)); ++ ASSERT_EQ(0, unlink(usr_env)); ++ ASSERT_EQ(0, unlink(usr_conf)); ++ ASSERT_EQ(0, rmdir(dir_usr_etc_security)); ++ ASSERT_EQ(0, rmdir(dir_usr_etc)); ++ ASSERT_EQ(0, rmdir(dir_usr)); ++ ASSERT_EQ(0, rmdir(dir)); + } + + static void +@@ -191,6 +221,36 @@ main(void) + const char *env2[] = { "test_value=foo", "test2_value=bar", NULL }; + check_env(env2); + ++#if defined (USE_ECONF) && defined (VENDORDIR) ++ ++ /* envfile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "session required %s/.libs/%s.so" ++ " conffile=%s envfile=%s/%s/\n", ++ cwd, MODULE_NAME, ++ "/dev/null", ++ cwd, dir)); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ const char *env3[] = {"usr_etc_test=foo", "usr_etc_test2=bar", NULL}; ++ check_env(env3); ++ ++ /* conffile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */ ++ ASSERT_NE(NULL, fp = fopen(service_file, "w")); ++ ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" ++ "session required %s/.libs/%s.so" ++ " conffile=%s/%s/ envfile=%s\n", ++ cwd, MODULE_NAME, ++ cwd, dir, ++ "/dev/null")); ++ ASSERT_EQ(0, fclose(fp)); ++ ++ const char *env4[] = {"PAGER=emacs", "MANPAGER=less", NULL}; ++ check_env(env4); ++ ++#endif ++ + /* cleanup */ + cleanup(); + ASSERT_EQ(0, unlink(service_file)); diff --git a/pam_pwhistory-docu.patch b/pam_pwhistory-docu.patch new file mode 100644 index 0000000..499fbc6 --- /dev/null +++ b/pam_pwhistory-docu.patch @@ -0,0 +1,264 @@ +diff --git a/modules/pam_pwhistory/Makefile.am b/modules/pam_pwhistory/Makefile.am +index 8a4dbcb2..c29a8e11 100644 +--- a/modules/pam_pwhistory/Makefile.am ++++ b/modules/pam_pwhistory/Makefile.am +@@ -9,9 +9,10 @@ MAINTAINERCLEANFILES = $(MANS) README + EXTRA_DIST = $(XMLS) + + if HAVE_DOC +-dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 ++dist_man_MANS = pam_pwhistory.8 pwhistory_helper.8 pwhistory.conf.5 + endif +-XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml ++XMLS = README.xml pam_pwhistory.8.xml pwhistory_helper.8.xml \ ++ pwhistory.conf.5.xml + dist_check_SCRIPTS = tst-pam_pwhistory + TESTS = $(dist_check_SCRIPTS) + +diff --git a/modules/pam_pwhistory/pam_pwhistory.8.xml b/modules/pam_pwhistory/pam_pwhistory.8.xml +index d88115c2..2a8fa7f6 100644 +--- a/modules/pam_pwhistory/pam_pwhistory.8.xml ++++ b/modules/pam_pwhistory/pam_pwhistory.8.xml +@@ -36,6 +36,12 @@ + + authtok_type=STRING + ++ ++ file=/path/filename ++ ++ ++ conf=/path/to/config-file ++ + + + +@@ -104,7 +110,7 @@ + + + The last N passwords for each +- user are saved in /etc/security/opasswd. ++ user are saved. + The default is 10. Value of + 0 makes the module to keep the existing + contents of the opasswd file unchanged. +@@ -137,7 +143,39 @@ + + + ++ ++ ++ ++ ++ ++ ++ Store password history in file /path/filename ++ rather than the default location. The default location is ++ /etc/security/opasswd. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Use another configuration file instead of the default ++ /etc/security/pwhistory.conf. ++ ++ ++ ++ + ++ ++ The options for configuring the module behavior are described in the ++ pwhistory.conf ++ 5 manual page. The options ++ specified on the module command line override the values from the ++ configuration file. ++ + + + +@@ -213,7 +251,7 @@ password required pam_unix.so use_authtok + + /etc/security/opasswd + +- File with password history ++ Default file with password history + + + +@@ -222,6 +260,9 @@ password required pam_unix.so use_authtok + + SEE ALSO + ++ ++ pwhistory.conf5 ++ , + + pam.conf5 + , +diff --git a/modules/pam_pwhistory/pwhistory.conf.5.xml b/modules/pam_pwhistory/pwhistory.conf.5.xml +new file mode 100644 +index 00000000..bac5ffed +--- /dev/null ++++ b/modules/pam_pwhistory/pwhistory.conf.5.xml +@@ -0,0 +1,155 @@ ++ ++ ++ ++ ++ ++ ++ pwhistory.conf ++ 5 ++ Linux-PAM Manual ++ ++ ++ ++ pwhistory.conf ++ pam_pwhistory configuration file ++ ++ ++ ++ ++ DESCRIPTION ++ ++ pwhistory.conf provides a way to configure the ++ default settings for saving the last passwords for each user. ++ This file is read by the pam_pwhistory module and is the ++ preferred method over configuring pam_pwhistory directly. ++ ++ ++ The file has a very simple name = value format with possible comments ++ starting with # character. The whitespace at the beginning of line, end ++ of line, and around the = sign is ignored. ++ ++ ++ ++ ++ ++ OPTIONS ++ ++ ++ ++ ++ ++ ++ ++ Turns on debugging via ++ ++ syslog3 ++ . ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ If this option is set, the check is enforced for root, too. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ The last N passwords for each ++ user are saved. ++ The default is 10. Value of ++ 0 makes the module to keep the existing ++ contents of the opasswd file unchanged. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Prompt user at most N times ++ before returning with error. The default is 1. ++ ++ ++ ++ ++ ++ ++ ++ ++ ++ Store password history in file ++ /path/filename rather than the default ++ location. The default location is ++ /etc/security/opasswd. ++ ++ ++ ++ ++ ++ ++ ++ EXAMPLES ++ ++ /etc/security/pwhistory.conf file example: ++ ++ ++debug ++remember=5 ++file=/tmp/opasswd ++ ++ ++ ++ ++ FILES ++ ++ ++ /etc/security/pwhistory.conf ++ ++ the config file for custom options ++ ++ ++ ++ ++ ++ ++ SEE ALSO ++ ++ ++ pwhistory8 ++ , ++ ++ pam_pwhistory8 ++ , ++ ++ pam.conf5 ++ , ++ ++ pam.d5 ++ , ++ ++ pam8 ++ ++ ++ ++ ++ ++ AUTHOR ++ ++ pam_pwhistory was written by Thorsten Kukuk. The support for ++ pwhistory.conf was written by Iker Pedrosa. ++ ++ ++ ++ + diff --git a/tst-pam_env-retval.c b/tst-pam_env-retval.c deleted file mode 100644 index 524d183..0000000 --- a/tst-pam_env-retval.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Check pam_env return values. - * - * Copyright (c) 2020-2022 Dmitry V. Levin - * Copyright (c) 2022 Stefan Schubert - */ - -#include "test_assert.h" - -#include -#include -#include -#include -#include -#include -#include - -#define MODULE_NAME "pam_env" -#define TEST_NAME "tst-" MODULE_NAME "-retval" -#define TEST_NAME_DIR TEST_NAME ".dir" - -static const char service_file[] = TEST_NAME ".service"; -static const char missing_file[] = TEST_NAME ".missing"; -static const char dir[] = TEST_NAME_DIR; -static const char dir_usr[] = TEST_NAME_DIR "/usr"; -static const char dir_usr_etc[] = TEST_NAME_DIR "/usr/etc"; -static const char dir_usr_etc_security[] = TEST_NAME_DIR "/usr/etc/security"; -static const char my_conf[] = TEST_NAME ".conf"; -static const char my_env[] = TEST_NAME ".env"; -static const char usr_env[] = TEST_NAME_DIR "/usr/etc/environment"; -static const char usr_conf[] = TEST_NAME_DIR "/usr/etc/security/pam_env.conf"; - -static struct pam_conv conv; - -static void -setup(void) -{ - FILE *fp; - - ASSERT_EQ(0, mkdir(dir, 0755)); - ASSERT_EQ(0, mkdir(dir_usr, 0755)); - ASSERT_EQ(0, mkdir(dir_usr_etc, 0755)); - ASSERT_EQ(0, mkdir(dir_usr_etc_security, 0755)); - - ASSERT_NE(NULL, fp = fopen(my_conf, "w")); - ASSERT_LT(0, fprintf(fp, - "EDITOR\tDEFAULT=vim\n" - "PAGER\tDEFAULT=more\n")); - ASSERT_EQ(0, fclose(fp)); - - ASSERT_NE(NULL, fp = fopen(my_env, "w")); - ASSERT_LT(0, fprintf(fp, - "test_value=foo\n" - "test2_value=bar\n")); - ASSERT_EQ(0, fclose(fp)); - - ASSERT_NE(NULL, fp = fopen(usr_env, "w")); - ASSERT_LT(0, fprintf(fp, - "usr_etc_test=foo\n" - "usr_etc_test2=bar\n")); - ASSERT_EQ(0, fclose(fp)); - - ASSERT_NE(NULL, fp = fopen(usr_conf, "w")); - ASSERT_LT(0, fprintf(fp, - "PAGER DEFAULT=emacs\n" - "MANPAGER DEFAULT=less\n")); - ASSERT_EQ(0, fclose(fp)); -} - -static void -cleanup(void) -{ - ASSERT_EQ(0, unlink(my_conf)); - ASSERT_EQ(0, unlink(my_env)); - ASSERT_EQ(0, unlink(usr_env)); - ASSERT_EQ(0, unlink(usr_conf)); - ASSERT_EQ(0, rmdir(dir_usr_etc_security)); - ASSERT_EQ(0, rmdir(dir_usr_etc)); - ASSERT_EQ(0, rmdir(dir_usr)); - ASSERT_EQ(0, rmdir(dir)); -} - -static void -check_array(const char **array1, char **array2) -{ - for (const char **a1 = array1; *a1 != NULL; ++a1) { - char **a2; - for (a2 = array2; *a2 != NULL; ++a2) { - if (strcmp(*a1, *a2) == 0) - break; - } - ASSERT_NE(NULL, *a2); - } -} - -static void -check_env(const char **list) -{ - pam_handle_t *pamh = NULL; - - ASSERT_EQ(PAM_SUCCESS, - pam_start_confdir(service_file, "", &conv, ".", &pamh)); - ASSERT_NE(NULL, pamh); - - ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0)); - - char **env_list = pam_getenvlist(pamh); - ASSERT_NE(NULL, env_list); - - check_array(list, env_list); - - for (char **e = env_list; *e != NULL; ++e) - free(*e); - free(env_list); - - ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); -} - -int -main(void) -{ - pam_handle_t *pamh = NULL; - FILE *fp; - char cwd[PATH_MAX]; - - ASSERT_NE(NULL, getcwd(cwd, sizeof(cwd))); - - setup(); - - /* - * When conffile= specifies a missing file, all methods except - * pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE. - * The return code of the stack where every module returns PAM_IGNORE - * is PAM_PERM_DENIED. - */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "auth required %s/.libs/%s.so conffile=%s/%s\n" - "account required %s/.libs/%s.so conffile=%s/%s\n" - "password required %s/.libs/%s.so conffile=%s/%s\n" - "session required %s/.libs/%s.so conffile=%s/%s\n", - cwd, MODULE_NAME, cwd, missing_file, - cwd, MODULE_NAME, cwd, missing_file, - cwd, MODULE_NAME, cwd, missing_file, - cwd, MODULE_NAME, cwd, missing_file)); - ASSERT_EQ(0, fclose(fp)); - - ASSERT_EQ(PAM_SUCCESS, - pam_start_confdir(service_file, "", &conv, ".", &pamh)); - ASSERT_NE(NULL, pamh); - ASSERT_EQ(PAM_PERM_DENIED, pam_authenticate(pamh, 0)); - ASSERT_EQ(PAM_PERM_DENIED, pam_setcred(pamh, 0)); - ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0)); - ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0)); - ASSERT_EQ(PAM_PERM_DENIED, pam_open_session(pamh, 0)); - ASSERT_EQ(PAM_PERM_DENIED, pam_close_session(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); - pamh = NULL; - - /* - * When conffile= specifies a missing file, all methods except - * pam_sm_acct_mgmt and pam_sm_chauthtok return PAM_IGNORE. - * pam_permit is added after pam_env to convert PAM_IGNORE to PAM_SUCCESS. - */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "auth required %s/.libs/%s.so conffile=%s/%s\n" - "auth required %s/../pam_permit/.libs/pam_permit.so\n" - "account required %s/.libs/%s.so conffile=%s/%s\n" - "account required %s/../pam_permit/.libs/pam_permit.so\n" - "password required %s/.libs/%s.so conffile=%s/%s\n" - "password required %s/../pam_permit/.libs/pam_permit.so\n" - "session required %s/.libs/%s.so conffile=%s/%s\n" - "session required %s/../pam_permit/.libs/pam_permit.so\n", - cwd, MODULE_NAME, cwd, missing_file, cwd, - cwd, MODULE_NAME, cwd, missing_file, cwd, - cwd, MODULE_NAME, cwd, missing_file, cwd, - cwd, MODULE_NAME, cwd, missing_file, cwd)); - ASSERT_EQ(0, fclose(fp)); - - ASSERT_EQ(PAM_SUCCESS, - pam_start_confdir(service_file, "", &conv, ".", &pamh)); - ASSERT_NE(NULL, pamh); - ASSERT_EQ(PAM_SUCCESS, pam_authenticate(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_setcred(pamh, 0)); - ASSERT_EQ(PAM_SERVICE_ERR, pam_acct_mgmt(pamh, 0)); - ASSERT_EQ(PAM_SERVICE_ERR, pam_chauthtok(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_open_session(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_close_session(pamh, 0)); - ASSERT_EQ(PAM_SUCCESS, pam_end(pamh, 0)); - pamh = NULL; - - /* - * conffile= specifies an existing file, - * envfile= specifies an empty file. - */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "session required %s/.libs/%s.so" - " conffile=%s/%s envfile=%s\n", - cwd, MODULE_NAME, - cwd, my_conf, "/dev/null")); - ASSERT_EQ(0, fclose(fp)); - - const char *env1[] = { "EDITOR=vim", "PAGER=more", NULL }; - check_env(env1); - - /* - * conffile= specifies an empty file, - * envfile= specifies an existing file. - */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "session required %s/.libs/%s.so" - " conffile=%s envfile=%s/%s\n", - cwd, MODULE_NAME, - "/dev/null", cwd, my_env)); - ASSERT_EQ(0, fclose(fp)); - - const char *env2[] = { "test_value=foo", "test2_value=bar", NULL }; - check_env(env2); - -#if defined (USE_ECONF) && defined (VENDORDIR) - - /* envfile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "session required %s/.libs/%s.so" - " conffile=%s envfile=%s/%s/\n", - cwd, MODULE_NAME, - "/dev/null", - cwd, dir)); - ASSERT_EQ(0, fclose(fp)); - - const char *env3[] = {"usr_etc_test=foo", "usr_etc_test2=bar", NULL}; - check_env(env3); - - /* conffile is a directory. So values will be read from {TEST_NAME_DIR}/usr/etc and {TEST_NAME_DIR}/etc */ - ASSERT_NE(NULL, fp = fopen(service_file, "w")); - ASSERT_LT(0, fprintf(fp, "#%%PAM-1.0\n" - "session required %s/.libs/%s.so" - " conffile=%s/%s/ envfile=%s\n", - cwd, MODULE_NAME, - cwd, dir, - "/dev/null")); - ASSERT_EQ(0, fclose(fp)); - - const char *env4[] = {"PAGER=emacs", "MANPAGER=less", NULL}; - check_env(env4); - -#endif - - /* cleanup */ - cleanup(); - ASSERT_EQ(0, unlink(service_file)); - - return 0; -}