diff -Nr -p2 ./postfix-2.0.7/README_FILES/PAM_README ./postfix-2.0.7-my/README_FILES/PAM_README
*** ./postfix-2.0.7/README_FILES/PAM_README	Thu Jan  1 07:00:00 1970
--- ./postfix-2.0.7-my/README_FILES/PAM_README	Tue Apr 22 15:13:26 2003
***************
*** 0 ****
--- 1,26 ----
+ PAM map type for Postfix.
+ 
+ Written by Andrew I Baznikin <dikiyobraz@mail.ru>, JSC ISP "Tel", Russia.
+ 
+ In order to build postfix with PAM map support, you will need to add
+ -DHAS_PAM and the libpam library to AUXLIBS, for example:
+ 
+ make -f Makefile.init makefiles \
+  'CCARGS=-DHAS_PAM' \
+  'AUXLIBS=-L/usr/lib -lpam'
+ 
+ then, just run 'make'.
+ 
+ Once postfix is built with PAM map support, you can specify a map type
+ in main.cf like this:
+ 
+ local_recipient_maps = pam:smtpcheck
+ 
+ In this example 'smtpcheck' is service name, applicant is e-mail address of recipient.
+ Facility is always "auth". See pam(8) for details.
+ 
+ Add some lines to /etc/pam.conf (or /etc/pam.d/<servicename>) :
+  #smtpcheck	auth	sufficient	pam_permit.so		debug try_first_pass
+  #smtpcheck	auth	sufficient	pam_deny.so		debug try_first_pass
+  smtpcheck	auth	sufficient	pam_unix.so		debug try_first_pass
+  smtpcheck	auth	required	pam_radius.so		debug try_first_pass
diff -Nr -p2 ./postfix-2.0.7/conf/postfix-files ./postfix-2.0.7-my/conf/postfix-files
*** ./postfix-2.0.7/conf/postfix-files	Mon Jan 13 00:08:12 2003
--- ./postfix-2.0.7-my/conf/postfix-files	Tue Apr 22 15:13:27 2003
*************** $readme_directory/MYSQL_README:f:root:-:
*** 186,189 ****
--- 186,190 ----
  $readme_directory/NFS_README:f:root:-:644
  $readme_directory/PACKAGE_README:f:root:-:644
+ $readme_directory/PAM_README:f:root:-:644
  $readme_directory/PCRE_README:f:root:-:644
  $readme_directory/QMQP_README:f:root:-:644
diff -Nr -p2 ./postfix-2.0.7/src/util/Makefile.in ./postfix-2.0.7-my/src/util/Makefile.in
*** ./postfix-2.0.7/src/util/Makefile.in	Sun Mar 16 07:41:13 2003
--- ./postfix-2.0.7-my/src/util/Makefile.in	Tue Apr 22 15:13:27 2003
*************** SRCS	= alldig.c argv.c argv_split.c attr
*** 5,10 ****
  	dict.c dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \
  	dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \
! 	dict_nisplus.c dict_open.c dict_pcre.c dict_regexp.c dict_static.c \
! 	dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
  	environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
  	file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
--- 5,10 ----
  	dict.c dict_alloc.c dict_db.c dict_dbm.c dict_debug.c dict_env.c \
  	dict_ht.c dict_ldap.c dict_mysql.c dict_ni.c dict_nis.c \
! 	dict_nisplus.c dict_open.c dict_pam.c dict_pcre.c dict_regexp.c \
! 	dict_static.c dict_tcp.c dict_unix.c dir_forest.c doze.c duplex_pipe.c \
  	environ.c events.c exec_command.c fifo_listen.c fifo_trigger.c \
  	file_limit.c find_inet.c fsspace.c fullname.c get_domainname.c \
*************** OBJS	= alldig.o argv.o argv_split.o attr
*** 33,38 ****
  	dict.o dict_alloc.o dict_db.o dict_dbm.o dict_debug.o dict_env.o \
  	dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
! 	dict_nisplus.o dict_open.o dict_pcre.o dict_regexp.o dict_static.o \
! 	dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
  	environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
  	file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
--- 33,38 ----
  	dict.o dict_alloc.o dict_db.o dict_dbm.o dict_debug.o dict_env.o \
  	dict_ht.o dict_ldap.o dict_mysql.o dict_ni.o dict_nis.o \
! 	dict_nisplus.o dict_open.o dict_pam.o dict_pcre.o dict_regexp.o \
! 	dict_static.o dict_tcp.o dict_unix.o dir_forest.o doze.o duplex_pipe.o \
  	environ.o events.o exec_command.o fifo_listen.o fifo_trigger.o \
  	file_limit.o find_inet.o fsspace.o fullname.o get_domainname.o \
*************** HDRS	= argv.h attr.h base64_code.h binha
*** 59,64 ****
  	connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
  	dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
! 	dict_nisplus.h dict_pcre.h dict_regexp.h dict_static.h dict_tcp.h \
! 	dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
  	fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
  	htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
--- 59,64 ----
  	connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
  	dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
! 	dict_nisplus.h dict_pam.h dict_pcre.h dict_regexp.h dict_static.h \
! 	dict_tcp.h dict_unix.h dir_forest.h events.h exec_command.h find_inet.h \
  	fsspace.h fullname.h get_domainname.h get_hostname.h hex_quote.h \
  	htable.h inet_addr_host.h inet_addr_list.h inet_addr_local.h \
*************** dict_open.o: dict_ni.h
*** 616,619 ****
--- 616,620 ----
  dict_open.o: dict_ldap.h
  dict_open.o: dict_mysql.h
+ dict_open.o: dict_pam.h
  dict_open.o: dict_pcre.h
  dict_open.o: dict_regexp.h
*************** dict_open.o: vstring.h
*** 623,626 ****
--- 624,636 ----
  dict_open.o: split_at.h
  dict_open.o: htable.h
+ dict_pam.o: dict_pam.c
+ dict_pam.o: sys_defs.h
+ dict_pam.o: mymalloc.h
+ dict_pam.o: msg.h
+ dict_pam.o: dict.h
+ dict_pam.o: vstream.h
+ dict_pam.o: vbuf.h
+ dict_pam.o: argv.h
+ dict_pam.o: dict_pam.h
  dict_pcre.o: dict_pcre.c
  dict_pcre.o: sys_defs.h
diff -Nr -p2 ./postfix-2.0.7/src/util/dict_open.c ./postfix-2.0.7-my/src/util/dict_open.c
*** ./postfix-2.0.7/src/util/dict_open.c	Sun Jan  5 08:07:25 2003
--- ./postfix-2.0.7-my/src/util/dict_open.c	Tue Apr 22 15:13:27 2003
***************
*** 175,178 ****
--- 175,179 ----
  #include <dict_ldap.h>
  #include <dict_mysql.h>
+ #include <dict_pam.h>
  #include <dict_pcre.h>
  #include <dict_regexp.h>
*************** static DICT_OPEN_INFO dict_open_info[] =
*** 223,226 ****
--- 224,230 ----
  #ifdef HAS_POSIX_REGEXP
      DICT_TYPE_REGEXP, dict_regexp_open,
+ #endif
+ #ifdef HAS_PAM
+     DICT_TYPE_PAM, dict_pam_open,
  #endif
      DICT_TYPE_STATIC, dict_static_open,
diff -Nr -p2 ./postfix-2.0.7/src/util/dict_pam.c ./postfix-2.0.7-my/src/util/dict_pam.c
*** ./postfix-2.0.7/src/util/dict_pam.c	Thu Jan  1 07:00:00 1970
--- ./postfix-2.0.7-my/src/util/dict_pam.c	Fri Apr 25 13:35:17 2003
***************
*** 0 ****
--- 1,148 ----
+ /*++
+ /* NAME
+ /*	dict_pam 3
+ /* SUMMARY
+ /*	dictionary manager interface to PAM
+ /* SYNOPSIS
+ /*	#include <dict_pam.h>
+ /*
+ /*	DICT	*dict_pam_open(service, dummy, dict_flags)
+ /*	const char *service;
+ /*	int	dummy;
+ /*	int	dict_flags;
+ /* DESCRIPTION
+ /*	dict_pam_open() implements a dictionary that returns
+ /*	as lookup result the key value on PAM_SUCCESS
+ /*	and 0 on any other.
+ /*
+ /*	The \fIdummy\fR argument is ignored.
+ /* SEE ALSO
+ /*	dict(3) generic dictionary manager
+ /* LICENSE
+ /* .ad
+ /* .fi
+ /*	The Secure Mailer license must be distributed with this software.
+ /* AUTHOR(S)
+ /*	Andrew I Baznikin
+ /*	dikiyobraz@mail.ru
+ /*	http://d.scn.ru
+ /*--*/
+ 
+ /* System library. */
+ 
+ #include "sys_defs.h"
+ 
+ #ifdef HAS_PAM
+ #include <unistd.h>
+ #include <security/pam_appl.h>
+ 
+ /* Utility library. */
+ 
+ #include "mymalloc.h"
+ #include "msg.h"
+ #include "vstring.h"
+ #include "dict.h"
+ #include "dict_pam.h"
+ 
+ int converse(int, const struct pam_message **, struct pam_response **, void *);
+ 
+ typedef struct {
+ 	DICT dict;
+ 	VSTRING *service;
+ } DICT_PAM;
+ 
+ /* answer 'Ok' on any request .) */
+ int converse(int n, const struct pam_message **msg,
+ 	    struct pam_response **resp, void *data)
+ {
+     char buf[PAM_MAX_RESP_SIZE];
+     int i;
+ 
+     data = data;
+     if (n <= 0 || n > PAM_MAX_NUM_MSG)
+ 	return (PAM_CONV_ERR);
+     if ((*resp = calloc(n, sizeof **resp)) == NULL)
+ 	return (PAM_BUF_ERR);
+     for (i = 0; i < n; ++i) {
+         resp[i]->resp_retcode = 0;
+         resp[i]->resp = strdup(msg[i]->msg);
+     }
+ 
+     return (PAM_SUCCESS);
+ }
+ 
+ 
+ /* dict_pam_lookup - access PAM */
+ 
+ static const char *dict_pam_lookup(DICT *dict, const char *name)
+ {
+     DICT_PAM *dp = (DICT_PAM *) dict;
+     int pam_err;
+ 
+     static pam_handle_t *pamh;
+     static struct pam_conv pamc;
+ 
+     dict_errno = 0;
+     pamc.conv = &converse;
+     if ((pam_err = pam_start( vstring_str(dp->service), name, &pamc, &pamh))
+ 	    != PAM_SUCCESS)
+ 	goto pamerr;
+ 
+     if (msg_verbose)
+         msg_info("pam: dict_pam_lookup %s with service '%s'", name, vstring_str(dp->service));
+ 
+      /* authenticate the applicant */
+     if ((pam_err = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
+         goto pamerr;
+ 
+     if (msg_verbose)
+         msg_info("pam: dict_pam_lookup success");
+     return (name);
+ 
+     pamerr:
+ 	if (msg_verbose)
+     	    msg_warn("PAM error code %d (%s)", pam_err, pam_strerror(pamh, pam_err));
+ 
+ /*	if ( pam_err == PAM_SERVICE_ERR || pam_err == PAM_AUTHINFO_UNAVAIL ) { */
+ 	if ( pam_err != PAM_PERM_DENIED && pam_err != PAM_AUTH_ERR) {
+ 	    msg_error("PAM service failure! Possibly, need admin intervention");
+ 	    dict_errno = DICT_ERR_RETRY;
+ 	}
+         pam_end(pamh, pam_err);
+         return (0);
+ }
+ 
+ /* dict_pam_close - close PAM dictionary */
+ 
+ static void dict_pam_close(DICT *dict)
+ {
+     DICT_PAM *dp = (DICT_PAM *) dict;
+ 
+     if (msg_verbose)
+         msg_info("pam: dict_pam_close");
+     vstring_free(dp->service);
+     dict_free(dict);
+ }
+ 
+ /* dict_pam_open - make association with PAM */
+ 
+ DICT   *dict_pam_open(const char *service, int param, int dict_flags)
+ {
+     DICT_PAM   *dp;
+     VSTRING *s, *f;
+ 
+     if (msg_verbose)
+         msg_info("pam: dict_pam_open: service %s, param %d, dict_flags %d ", service, param, dict_flags);
+ 
+     dp = (DICT_PAM *) dict_alloc(DICT_TYPE_PAM, service, sizeof(DICT_PAM));
+ 
+     dp->service = vstring_alloc(10);
+ 
+     vstring_strcpy(dp->service, service);
+     dp->dict.lookup = dict_pam_lookup;
+     dp->dict.close = dict_pam_close;
+     dp->dict.flags = dict_flags | DICT_FLAG_FIXED;
+ 
+     return (DICT_DEBUG (&dp->dict));
+ }
+ #endif
diff -Nr -p2 ./postfix-2.0.7/src/util/dict_pam.h ./postfix-2.0.7-my/src/util/dict_pam.h
*** ./postfix-2.0.7/src/util/dict_pam.h	Thu Jan  1 07:00:00 1970
--- ./postfix-2.0.7-my/src/util/dict_pam.h	Tue Apr 22 15:13:27 2003
***************
*** 0 ****
--- 1,36 ----
+ #ifndef _DICT_PAM_H_INCLUDED_
+ #define _DICT_PAM_H_INCLUDED_
+ 
+ /*++
+ /* NAME
+ /*	dict_pam 3h
+ /* SUMMARY
+ /*	dictionary manager interface to PAM
+ /* SYNOPSIS
+ /*	#include <dict_pam.h>
+ /* DESCRIPTION
+ /* .nf
+ 
+  /*
+   * Utility library.
+   */
+ #include <dict.h>
+ 
+  /*
+   * External interface.
+   */
+ #define DICT_TYPE_PAM	"pam"
+ 
+ extern DICT *dict_pam_open(const char *, int, int);
+ 
+ /* LICENSE
+ /* .ad
+ /* .fi
+ /*	The Secure Mailer license must be distributed with this software.
+ /* AUTHOR(S)
+ /*	Andrew I Baznikin
+ /*	dikiyobraz@mail.ru
+ /*	http://d.scn.ru
+ /*--*/
+ 
+ #endif
