diff options
author | Steve Langasek <vorlon@debian.org> | 2009-08-24 03:06:11 -0700 |
---|---|---|
committer | Steve Langasek <vorlon@debian.org> | 2019-01-08 21:25:43 -0800 |
commit | 78915f5a06936cc24cf7776c8b53d08b6ea3616c (patch) | |
tree | 6325216d4660f2a33d2161d71302b8c3f47c76e5 /modules/pam_exec | |
parent | fdd6439782a15a1abe342044e07e5f7501ae73de (diff) | |
parent | 212b52cf29c06cc209bc8ac0540dbab1acdf1464 (diff) | |
download | pam-78915f5a06936cc24cf7776c8b53d08b6ea3616c.tar.gz pam-78915f5a06936cc24cf7776c8b53d08b6ea3616c.tar.bz2 pam-78915f5a06936cc24cf7776c8b53d08b6ea3616c.zip |
merge upstream version 1.1.0
Diffstat (limited to 'modules/pam_exec')
-rw-r--r-- | modules/pam_exec/Makefile.in | 75 | ||||
-rw-r--r-- | modules/pam_exec/README | 10 | ||||
-rw-r--r-- | modules/pam_exec/pam_exec.8 | 258 | ||||
-rw-r--r-- | modules/pam_exec/pam_exec.8.xml | 37 | ||||
-rw-r--r-- | modules/pam_exec/pam_exec.c | 195 |
5 files changed, 463 insertions, 112 deletions
diff --git a/modules/pam_exec/Makefile.in b/modules/pam_exec/Makefile.in index fac7a4e6..598d2018 100644 --- a/modules/pam_exec/Makefile.in +++ b/modules/pam_exec/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated by automake 1.10.1 from Makefile.am. +# Makefile.in generated by automake 1.10.2 from Makefile.am. # @configure_input@ # Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, @@ -42,13 +42,16 @@ subdir = modules/pam_exec DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ - $(top_srcdir)/m4/iconv.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/japhar_grep_cflags.m4 \ $(top_srcdir)/m4/jh_path_xml_catalog.m4 \ $(top_srcdir)/m4/ld-O1.m4 $(top_srcdir)/m4/ld-as-needed.m4 \ $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libprelude.m4 \ - $(top_srcdir)/m4/nls.m4 $(top_srcdir)/m4/po.m4 \ - $(top_srcdir)/m4/progtest.m4 $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ $(top_srcdir)/configure.in am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) @@ -101,23 +104,19 @@ CCDEPMODE = @CCDEPMODE@ CFLAGS = @CFLAGS@ CPP = @CPP@ CPPFLAGS = @CPPFLAGS@ -CXX = @CXX@ -CXXCPP = @CXXCPP@ -CXXDEPMODE = @CXXDEPMODE@ -CXXFLAGS = @CXXFLAGS@ CYGPATH_W = @CYGPATH_W@ DEFS = @DEFS@ DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ -ECHO = @ECHO@ +DUMPBIN = @DUMPBIN@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ EXEEXT = @EXEEXT@ -F77 = @F77@ -FFLAGS = @FFLAGS@ +FGREP = @FGREP@ FO2PDF = @FO2PDF@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ GMSGFMT = @GMSGFMT@ GMSGFMT_015 = @GMSGFMT_015@ GREP = @GREP@ @@ -129,6 +128,7 @@ INSTALL_SCRIPT = @INSTALL_SCRIPT@ INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ INTLLIBS = @INTLLIBS@ INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ LDFLAGS = @LDFLAGS@ LEX = @LEX@ LEXLIB = @LEXLIB@ @@ -152,6 +152,7 @@ LIBPRELUDE_PTHREAD_CFLAGS = @LIBPRELUDE_PTHREAD_CFLAGS@ LIBS = @LIBS@ LIBSELINUX = @LIBSELINUX@ LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ LN_S = @LN_S@ LTLIBICONV = @LTLIBICONV@ LTLIBINTL = @LTLIBINTL@ @@ -161,15 +162,18 @@ MKDIR_P = @MKDIR_P@ MSGFMT = @MSGFMT@ MSGFMT_015 = @MSGFMT_015@ MSGMERGE = @MSGMERGE@ +NM = @NM@ NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ PACKAGE = @PACKAGE@ PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ PACKAGE_NAME = @PACKAGE_NAME@ PACKAGE_STRING = @PACKAGE_STRING@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ -PAM_READ_BOTH_CONFS = @PAM_READ_BOTH_CONFS@ PATH_SEPARATOR = @PATH_SEPARATOR@ PIE_CFLAGS = @PIE_CFLAGS@ PIE_LDFLAGS = @PIE_LDFLAGS@ @@ -183,10 +187,9 @@ SHELL = @SHELL@ STRIP = @STRIP@ USE_NLS = @USE_NLS@ VERSION = @VERSION@ -WITH_DEBUG = @WITH_DEBUG@ -WITH_PAMLOCKING = @WITH_PAMLOCKING@ XGETTEXT = @XGETTEXT@ XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ XMLCATALOG = @XMLCATALOG@ XMLLINT = @XMLLINT@ XML_CATALOG_FILE = @XML_CATALOG_FILE@ @@ -198,8 +201,7 @@ abs_srcdir = @abs_srcdir@ abs_top_builddir = @abs_top_builddir@ abs_top_srcdir = @abs_top_srcdir@ ac_ct_CC = @ac_ct_CC@ -ac_ct_CXX = @ac_ct_CXX@ -ac_ct_F77 = @ac_ct_F77@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ am__include = @am__include@ am__leading_dot = @am__leading_dot@ am__quote = @am__quote@ @@ -231,6 +233,7 @@ libdir = @libdir@ libexecdir = @libexecdir@ localedir = @localedir@ localstatedir = @localstatedir@ +lt_ECHO = @lt_ECHO@ mandir = @mandir@ mkdir_p = @mkdir_p@ oldincludedir = @oldincludedir@ @@ -245,6 +248,7 @@ sharedstatedir = @sharedstatedir@ srcdir = @srcdir@ sysconfdir = @sysconfdir@ target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ CLEANFILES = *~ @@ -267,8 +271,8 @@ $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ *$$dep*) \ - cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh \ - && exit 0; \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ exit 1;; \ esac; \ done; \ @@ -367,8 +371,8 @@ install-man8: $(man8_MANS) $(man_MANS) esac; \ done; \ for i in $$list; do \ - if test -f $(srcdir)/$$i; then file=$(srcdir)/$$i; \ - else file=$$i; fi; \ + if test -f $$i; then file=$$i; \ + else file=$(srcdir)/$$i; fi; \ ext=`echo $$i | sed -e 's/^.*\\.//'`; \ case "$$ext" in \ 8*) ;; \ @@ -407,7 +411,7 @@ ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) unique=`for i in $$list; do \ if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ done | \ - $(AWK) '{ files[$$0] = 1; nonemtpy = 1; } \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ END { if (nonempty) { for (i in files) print i; }; }'`; \ mkid -fID $$unique tags: TAGS @@ -450,7 +454,7 @@ distclean-tags: -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags check-TESTS: $(TESTS) - @failed=0; all=0; xfail=0; xpass=0; skip=0; ws='[ ]'; \ + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ srcdir=$(srcdir); export srcdir; \ list=' $(TESTS) '; \ if test -n "$$list"; then \ @@ -461,7 +465,7 @@ check-TESTS: $(TESTS) if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xpass=`expr $$xpass + 1`; \ failed=`expr $$failed + 1`; \ echo "XPASS: $$tst"; \ @@ -473,7 +477,7 @@ check-TESTS: $(TESTS) elif test $$? -ne 77; then \ all=`expr $$all + 1`; \ case " $(XFAIL_TESTS) " in \ - *$$ws$$tst$$ws*) \ + *[\ \ ]$$tst[\ \ ]*) \ xfail=`expr $$xfail + 1`; \ echo "XFAIL: $$tst"; \ ;; \ @@ -487,23 +491,36 @@ check-TESTS: $(TESTS) echo "SKIP: $$tst"; \ fi; \ done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ if test "$$failed" -eq 0; then \ if test "$$xfail" -eq 0; then \ - banner="All $$all tests passed"; \ + banner="$$All$$all $$tests passed"; \ else \ - banner="All $$all tests behaved as expected ($$xfail expected failures)"; \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ fi; \ else \ if test "$$xpass" -eq 0; then \ - banner="$$failed of $$all tests failed"; \ + banner="$$failed of $$all $$tests failed"; \ else \ - banner="$$failed of $$all tests did not behave as expected ($$xpass unexpected passes)"; \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ fi; \ fi; \ dashes="$$banner"; \ skipped=""; \ if test "$$skip" -ne 0; then \ - skipped="($$skip tests were not run)"; \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ dashes="$$skipped"; \ fi; \ diff --git a/modules/pam_exec/README b/modules/pam_exec/README index f0845205..14d1b9f0 100644 --- a/modules/pam_exec/README +++ b/modules/pam_exec/README @@ -8,8 +8,9 @@ pam_exec is a PAM module that can be used to run an external command. The child's environment is set to the current PAM environment list, as returned by pam_getenvlist(3) In addition, the following PAM items are exported as -environment variables: PAM_RHOST, PAM_RUSER, PAM_SERVICE, PAM_TTY, and PAM_USER -. +environment variables: PAM_RHOST, PAM_RUSER, PAM_SERVICE, PAM_TTY, PAM_USER and +PAM_TYPE, which contains one of the module types: account, auth, password, +open_session and close_session. OPTIONS @@ -17,6 +18,11 @@ debug Print debug information. +expose_authtok + + During authentication the calling command can read the password from stdin + (3). + log=file The output of the command is appended to file diff --git a/modules/pam_exec/pam_exec.8 b/modules/pam_exec/pam_exec.8 index da7c7830..834e5404 100644 --- a/modules/pam_exec/pam_exec.8 +++ b/modules/pam_exec/pam_exec.8 @@ -1,23 +1,181 @@ .\" Title: pam_exec -.\" Author: -.\" Generator: DocBook XSL Stylesheets v1.73.1 <http://docbook.sf.net/> -.\" Date: 04/16/2008 +.\" Author: [see the "AUTHOR" section] +.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/> +.\" Date: 06/16/2009 .\" Manual: Linux-PAM Manual .\" Source: Linux-PAM Manual +.\" Language: English .\" -.TH "PAM_EXEC" "8" "04/16/2008" "Linux-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_EXEC" "8" "06/16/2009" "Linux-PAM Manual" "Linux\-PAM Manual" +.\" ----------------------------------------------------------------- +.\" * (re)Define some macros +.\" ----------------------------------------------------------------- +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" toupper - uppercase a string (locale-aware) +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de toupper +.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ +\\$* +.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH-xref - format a cross-reference to an SH section +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de SH-xref +.ie n \{\ +.\} +.toupper \\$* +.el \{\ +\\$* +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SH - level-one heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SH +.\" put an extra blank line of space above the head in non-TTY output +.if t \{\ +.sp 1 +.\} +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[an-margin]u +.ti 0 +.HTML-TAG ".NH \\n[an-level]" +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +\." make the size of the head bigger +.ps +3 +.ft B +.ne (2v + 1u) +.ie n \{\ +.\" if n (TTY output), use uppercase +.toupper \\$* +.\} +.el \{\ +.nr an-break-flag 0 +.\" if not n (not TTY), use normal case (not uppercase) +\\$1 +.in \\n[an-margin]u +.ti 0 +.\" if not n (not TTY), put a border/line under subheading +.sp -.6 +\l'\n(.lu' +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" SS - level-two heading that works better for non-TTY output +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de1 SS +.sp \\n[PD]u +.nr an-level 1 +.set-an-margin +.nr an-prevailing-indent \\n[IN] +.fi +.in \\n[IN]u +.ti \\n[SN]u +.it 1 an-trap +.nr an-no-space-flag 1 +.nr an-break-flag 1 +.ps \\n[PS-SS]u +\." make the size of the head bigger +.ps +2 +.ft B +.ne (2v + 1u) +.if \\n[.$] \&\\$* +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BB/BE - put background/screen (filled box) around block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BB +.if t \{\ +.sp -.5 +.br +.in +2n +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EB +.if t \{\ +.if "\\$2"adjust-for-leading-newline" \{\ +.sp -1 +.\} +.br +.di +.in +.ll +.gcolor +.nr BW \\n(.lu-\\n(.i +.nr BH \\n(dn+.5v +.ne \\n(BHu+.5v +.ie "\\$2"adjust-for-leading-newline" \{\ +\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.el \{\ +\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[] +.\} +.in 0 +.sp -.5v +.nf +.BX +.in +.sp .5v +.fi +.\} +.. +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.\" BM/EM - put colored marker in margin next to block of text +.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +.de BM +.if t \{\ +.br +.ll -2n +.gcolor red +.di BX +.\} +.. +.de EM +.if t \{\ +.br +.di +.ll +.gcolor +.nr BH \\n(dn +.ne \\n(BHu +\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[] +.in 0 +.nf +.BX +.in +.fi +.\} +.. +.\" ----------------------------------------------------------------- +.\" * set default formatting +.\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l -.SH "NAME" -pam_exec - PAM module which calls an external command -.SH "SYNOPSIS" -.HP 12 -\fBpam_exec\.so\fR [debug] [seteuid] [quiet] [log=\fIfile\fR] \fIcommand\fR [\fI\.\.\.\fR] +.\" ----------------------------------------------------------------- +.\" * MAIN CONTENT STARTS HERE * +.\" ----------------------------------------------------------------- +.SH "Name" +pam_exec \- PAM module which calls an external command +.SH "Synopsis" +.fam C +.HP \w'\fBpam_exec\&.so\fR\ 'u +\fBpam_exec\&.so\fR [debug] [expose_authtok] [seteuid] [quiet] [log=\fIfile\fR] \fIcommand\fR [\fI\&.\&.\&.\fR] +.fam .SH "DESCRIPTION" .PP -pam_exec is a PAM module that can be used to run an external command\. +pam_exec is a PAM module that can be used to run an external command\&. .PP The child\'s environment is set to the current PAM environment list, as returned by \fBpam_getenvlist\fR(3) @@ -25,92 +183,132 @@ In addition, the following PAM items are exported as environment variables: \fIPAM_RHOST\fR, \fIPAM_RUSER\fR, \fIPAM_SERVICE\fR, -\fIPAM_TTY\fR, and -\fIPAM_USER\fR\. +\fIPAM_TTY\fR, +\fIPAM_USER\fR +and +\fIPAM_TYPE\fR, which contains one of the module types: +\fBaccount\fR, +\fBauth\fR, +\fBpassword\fR, +\fBopen_session\fR +and +\fBclose_session\fR\&. .SH "OPTIONS" .PP .PP \fBdebug\fR .RS 4 -Print debug information\. +Print debug information\&. +.RE +.PP +\fBexpose_authtok\fR +.RS 4 +During authentication the calling command can read the password from +\fBstdin\fR(3)\&. .RE .PP \fBlog=\fR\fB\fIfile\fR\fR .RS 4 The output of the command is appended to -\fIfile\fR +\FCfile\F[] .RE .PP \fBquiet\fR .RS 4 -Per default pam_exec\.so will echo the exit status of the external command if it fails\. Specifying this option will suppress the message\. +Per default pam_exec\&.so will echo the exit status of the external command if it fails\&. Specifying this option will suppress the message\&. .RE .PP \fBseteuid\fR .RS 4 -Per default pam_exec\.so will execute the external command with the real user ID of the calling process\. Specifying this option means the command is run with the effective user ID\. +Per default pam_exec\&.so will execute the external command with the real user ID of the calling process\&. Specifying this option means the command is run with the effective user ID\&. .RE -.SH "MODULE SERVICES PROVIDED" +.SH "MODULE TYPES PROVIDED" .PP -The services -\fBauth\fR, +All module types (\fBauth\fR, \fBaccount\fR, \fBpassword\fR and -\fBsession\fR -are supported\. +\fBsession\fR) are provided\&. .SH "RETURN VALUES" .PP .PP PAM_SUCCESS .RS 4 -The external command runs successfull\. +The external command was run successfully\&. .RE .PP PAM_SERVICE_ERR .RS 4 -No argument or a wrong number of arguments were given\. +No argument or a wrong number of arguments were given\&. .RE .PP PAM_SYSTEM_ERR .RS 4 -A system error occured or the command to execute failed\. +A system error occurred or the command to execute failed\&. .RE .PP PAM_IGNORE .RS 4 \fBpam_setcred\fR -was called, which does not execute the command\. +was called, which does not execute the command\&. .RE .SH "EXAMPLES" .PP Add the following line to -\fI/etc/pam\.d/passwd\fR +\FC/etc/pam\&.d/passwd\F[] to rebuild the NIS database after each local password change: .sp +.if n \{\ .RS 4 +.\} +.fam C +.ps -1 .nf - passwd optional pam_exec\.so seteuid make \-C /var/yp +.if t \{\ +.sp -1 +.\} +.BB lightgray adjust-for-leading-newline +.sp -1 + + passwd optional pam_exec\&.so seteuid make \-C /var/yp +.EB lightgray adjust-for-leading-newline +.if t \{\ +.sp 1 +.\} .fi +.fam +.ps +1 +.if n \{\ .RE +.\} .sp This will execute the command .sp +.if n \{\ .RS 4 +.\} +.fam C +.ps -1 .nf +.BB lightgray make \-C /var/yp +.EB lightgray .fi +.fam +.ps +1 +.if n \{\ .RE +.\} .sp -with effective user ID\. +with effective user ID\&. .SH "SEE ALSO" .PP \fBpam.conf\fR(5), -\fBpam.d\fR(8), +\fBpam.d\fR(5), \fBpam\fR(8) .SH "AUTHOR" .PP -pam_exec was written by Thorsten Kukuk <kukuk@thkukuk\.de>\. +pam_exec was written by Thorsten Kukuk <kukuk@thkukuk\&.de>\&. diff --git a/modules/pam_exec/pam_exec.8.xml b/modules/pam_exec/pam_exec.8.xml index f4dc1e15..1ca50dd5 100644 --- a/modules/pam_exec/pam_exec.8.xml +++ b/modules/pam_exec/pam_exec.8.xml @@ -22,6 +22,9 @@ debug </arg> <arg choice="opt"> + expose_authtok + </arg> + <arg choice="opt"> seteuid </arg> <arg choice="opt"> @@ -57,7 +60,11 @@ In addition, the following PAM items are exported as environment variables: <emphasis>PAM_RHOST</emphasis>, <emphasis>PAM_RUSER</emphasis>, <emphasis>PAM_SERVICE</emphasis>, - <emphasis>PAM_TTY</emphasis>, and <emphasis>PAM_USER</emphasis>. + <emphasis>PAM_TTY</emphasis>, <emphasis>PAM_USER</emphasis> and + <emphasis>PAM_TYPE</emphasis>, which contains one of the module + types: <option>account</option>, <option>auth</option>, + <option>password</option>, <option>open_session</option> and + <option>close_session</option>. </para> </refsect1> @@ -81,6 +88,20 @@ <varlistentry> <term> + <option>expose_authtok</option> + </term> + <listitem> + <para> + During authentication the calling command can read + the password from <citerefentry> + <refentrytitle>stdin</refentrytitle><manvolnum>3</manvolnum> + </citerefentry>. + </para> + </listitem> + </varlistentry> + + <varlistentry> + <term> <option>log=<replaceable>file</replaceable></option> </term> <listitem> @@ -123,11 +144,11 @@ </para> </refsect1> - <refsect1 id="pam_exec-services"> - <title>MODULE SERVICES PROVIDED</title> + <refsect1 id="pam_exec-types"> + <title>MODULE TYPES PROVIDED</title> <para> - The services <option>auth</option>, <option>account</option>, - <option>password</option> and <option>session</option> are supported. + All module types (<option>auth</option>, <option>account</option>, + <option>password</option> and <option>session</option>) are provided. </para> </refsect1> @@ -140,7 +161,7 @@ <term>PAM_SUCCESS</term> <listitem> <para> - The external command runs successfull. + The external command was run successfully. </para> </listitem> </varlistentry> @@ -158,7 +179,7 @@ <term>PAM_SYSTEM_ERR</term> <listitem> <para> - A system error occured or the command to execute failed. + A system error occurred or the command to execute failed. </para> </listitem> </varlistentry> @@ -199,7 +220,7 @@ <refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum> </citerefentry>, <citerefentry> - <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum> + <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum> </citerefentry>, <citerefentry> <refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum> diff --git a/modules/pam_exec/pam_exec.c b/modules/pam_exec/pam_exec.c index 14dddd54..7b2e402c 100644 --- a/modules/pam_exec/pam_exec.c +++ b/modules/pam_exec/pam_exec.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006 Thorsten Kukuk <kukuk@thkukuk.de> + * Copyright (c) 2006, 2008 Thorsten Kukuk <kukuk@thkukuk.de> * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -58,6 +58,7 @@ #include <security/pam_modules.h> #include <security/pam_modutil.h> #include <security/pam_ext.h> +#include <security/_pam_macros.h> #define ENV_ITEM(n) { (n), #n } static struct { @@ -71,15 +72,20 @@ static struct { ENV_ITEM(PAM_RUSER), }; + static int -call_exec (pam_handle_t *pamh, int argc, const char **argv) +call_exec (const char *pam_type, pam_handle_t *pamh, + int argc, const char **argv) { int debug = 0; int call_setuid = 0; int quiet = 0; + int expose_authtok = 0; int optargc; const char *logfile = NULL; + const char *authtok = NULL; pid_t pid; + int fds[2]; if (argc < 1) { pam_syslog (pamh, LOG_ERR, @@ -100,10 +106,63 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) call_setuid = 1; else if (strcasecmp (argv[optargc], "quiet") == 0) quiet = 1; + else if (strcasecmp (argv[optargc], "expose_authtok") == 0) + expose_authtok = 1; else break; /* Unknown option, assume program to execute. */ } + if (expose_authtok == 1) + { + if (strcmp (pam_type, "auth") != 0) + { + pam_syslog (pamh, LOG_ERR, + "expose_authtok not supported for type %s", pam_type); + expose_authtok = 0; + } + else + { + const void *void_pass; + int retval; + + retval = pam_get_item (pamh, PAM_AUTHTOK, &void_pass); + if (retval != PAM_SUCCESS) + { + if (debug) + pam_syslog (pamh, LOG_DEBUG, + "pam_get_item (PAM_AUTHTOK) failed, return %d", + retval); + return retval; + } + else if (void_pass == NULL) + { + char *resp = NULL; + + retval = pam_prompt (pamh, PAM_PROMPT_ECHO_OFF, + &resp, _("Password: ")); + + if (retval != PAM_SUCCESS) + { + _pam_drop (resp); + if (retval == PAM_CONV_AGAIN) + retval = PAM_INCOMPLETE; + return retval; + } + + pam_set_item (pamh, PAM_AUTHTOK, resp); + authtok = strdupa (resp); + _pam_drop (resp); + } + else + authtok = void_pass; + + if (pipe(fds) != 0) + { + pam_syslog (pamh, LOG_ERR, "Could not create pipe: %m"); + return PAM_SYSTEM_ERR; + } + } + } if (optargc >= argc) { pam_syslog (pamh, LOG_ERR, "No path given as argument"); @@ -117,6 +176,28 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) { int status = 0; pid_t retval; + + if (expose_authtok) /* send the password to the child */ + { + if (authtok != NULL) + { /* send the password to the child */ + if (debug) + pam_syslog (pamh, LOG_DEBUG, "send password to child"); + if (write(fds[1], authtok, strlen(authtok)+1) == -1) + pam_syslog (pamh, LOG_ERR, + "sending password to child failed: %m"); + authtok = NULL; + } + else + { + if (write(fds[1], "", 1) == -1) /* blank password */ + pam_syslog (pamh, LOG_ERR, + "sending password to child failed: %m"); + } + close(fds[0]); /* close here to avoid possible SIGPIPE above */ + close(fds[1]); + } + while ((retval = waitpid (pid, &status, 0)) == -1 && errno == EINTR); if (retval == (pid_t)-1) @@ -160,17 +241,40 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) { char **arggv; int i; + char **envlist, **tmp; + int envlen, nitems; + char *envstr; - for (i = 0; i < sysconf (_SC_OPEN_MAX); i++) - close (i); + if (expose_authtok) + { + /* reopen stdin as pipe */ + if (dup2(fds[0], STDIN_FILENO) == -1) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "dup2 of STDIN failed: %m"); + _exit (err); + } - /* New stdin. */ - if ((i = open ("/dev/null", O_RDWR)) < 0) + for (i = 0; i < sysconf (_SC_OPEN_MAX); i++) + { + if (i != STDIN_FILENO) + close (i); + } + } + else { - int err = errno; - pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m"); - exit (err); + for (i = 0; i < sysconf (_SC_OPEN_MAX); i++) + close (i); + + /* New stdin. */ + if ((i = open ("/dev/null", O_RDWR)) < 0) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m"); + _exit (err); + } } + /* New stdout and stderr. */ if (logfile) { @@ -183,7 +287,7 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) int err = errno; pam_syslog (pamh, LOG_ERR, "open of %s failed: %m", logfile); - exit (err); + _exit (err); } if (asprintf (&buffer, "*** %s", ctime (&tm)) > 0) { @@ -192,18 +296,22 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) } } else - if (dup (i) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "dup failed: %m"); - exit (err); - } + { + /* New stdout/stderr. */ + if ((i = open ("/dev/null", O_RDWR)) < 0) + { + int err = errno; + pam_syslog (pamh, LOG_ERR, "open of /dev/null failed: %m"); + _exit (err); + } + } + if (dup (i) == -1) - { + { int err = errno; pam_syslog (pamh, LOG_ERR, "dup failed: %m"); - exit (err); - } + _exit (err); + } if (call_setuid) if (setuid (geteuid ()) == -1) @@ -211,27 +319,24 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) int err = errno; pam_syslog (pamh, LOG_ERR, "setuid(%lu) failed: %m", (unsigned long) geteuid ()); - exit (err); + _exit (err); } if (setsid () == -1) { int err = errno; pam_syslog (pamh, LOG_ERR, "setsid failed: %m"); - exit (err); + _exit (err); } arggv = calloc (argc + 4, sizeof (char *)); if (arggv == NULL) - exit (ENOMEM); + _exit (ENOMEM); for (i = 0; i < (argc - optargc); i++) arggv[i] = strdup(argv[i+optargc]); arggv[i] = NULL; - char **envlist, **tmp; - int envlen, nitems; - /* * Set up the child's environment list. It consists of the PAM * environment, plus a few hand-picked PAM items. @@ -240,18 +345,18 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) for (envlen = 0; envlist[envlen] != NULL; ++envlen) /* nothing */ ; nitems = sizeof(env_items) / sizeof(*env_items); - tmp = realloc(envlist, (envlen + nitems + 1) * sizeof(*envlist)); + /* + 2 because of PAM_TYPE and NULL entry */ + tmp = realloc(envlist, (envlen + nitems + 2) * sizeof(*envlist)); if (tmp == NULL) { free(envlist); pam_syslog (pamh, LOG_ERR, "realloc environment failed: %m"); - exit (ENOMEM); + _exit (ENOMEM); } envlist = tmp; for (i = 0; i < nitems; ++i) { const void *item; - char *envstr; if (pam_get_item(pamh, env_items[i].item, &item) != PAM_SUCCESS || item == NULL) continue; @@ -259,25 +364,29 @@ call_exec (pam_handle_t *pamh, int argc, const char **argv) { free(envlist); pam_syslog (pamh, LOG_ERR, "prepare environment failed: %m"); - exit (ENOMEM); + _exit (ENOMEM); } envlist[envlen++] = envstr; envlist[envlen] = NULL; } + if (asprintf(&envstr, "PAM_TYPE=%s", pam_type) < 0) + { + free(envlist); + pam_syslog (pamh, LOG_ERR, "prepare environment failed: %m"); + _exit (ENOMEM); + } + envlist[envlen++] = envstr; + envlist[envlen] = NULL; + if (debug) pam_syslog (pamh, LOG_DEBUG, "Calling %s ...", arggv[0]); - if (execve (arggv[0], arggv, envlist) == -1) - { - int err = errno; - pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", - arggv[0]); - free(envlist); - exit (err); - } + execve (arggv[0], arggv, envlist); + i = errno; + pam_syslog (pamh, LOG_ERR, "execve(%s,...) failed: %m", arggv[0]); free(envlist); - exit (1); /* should never be reached. */ + _exit (i); } return PAM_SYSTEM_ERR; /* will never be reached. */ } @@ -286,7 +395,7 @@ PAM_EXTERN int pam_sm_authenticate (pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return call_exec ("auth", pamh, argc, argv); } PAM_EXTERN int @@ -304,28 +413,28 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, { if (flags & PAM_PRELIM_CHECK) return PAM_SUCCESS; - return call_exec (pamh, argc, argv); + return call_exec ("password", pamh, argc, argv); } PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return call_exec ("account", pamh, argc, argv); } PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return call_exec ("open_session", pamh, argc, argv); } PAM_EXTERN int pam_sm_close_session(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { - return call_exec (pamh, argc, argv); + return call_exec ("close_session", pamh, argc, argv); } #ifdef PAM_STATIC |