--- modules/pam_exec/pam_exec.8	2008-04-16 11:09:09.000000000 +0200
+++ modules/pam_exec/pam_exec.8	2009-06-16 10:33:15.000000000 +0200
@@ -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 @@
 \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>\&.
--- modules/pam_exec/pam_exec.8.xml	2008-02-04 16:27:31.000000000 +0100
+++ modules/pam_exec/pam_exec.8.xml	2009-06-16 09:35:09.000000000 +0200
@@ -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>
@@ -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>
--- modules/pam_exec/pam_exec.c	2008-02-18 14:18:43.000000000 +0100
+++ modules/pam_exec/pam_exec.c	2009-04-09 10:07:11.000000000 +0200
@@ -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 @@
   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_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 @@
     {
       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 @@
     {
       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 @@
 	      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 @@
 	    }
 	}
       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 @@
 	    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 @@
       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 @@
         {
           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_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 @@
 {
   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
--- modules/pam_exec/README	2008-04-16 11:09:10.000000000 +0200
+++ modules/pam_exec/README	2009-06-16 10:33:19.000000000 +0200
@@ -8,8 +8,9 @@
 
 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 @@
 
     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
