aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Murray <markm@FreeBSD.org>2001-05-03 09:36:08 +0000
committerMark Murray <markm@FreeBSD.org>2001-05-03 09:36:08 +0000
commit5791a4d4466a137893028f8243622286dae2bb0d (patch)
treef347e0c6cb6a7b2d9e9af0cc7052f5e0bb9c51e3
parentfff5887d38e30654e1d5da89af2ad7614c05cfc8 (diff)
downloadsrc-vendor/libpam.tar.gz
src-vendor/libpam.zip
Vendor import Linux PAM 0.75vendor/libpam
Notes
Notes: svn path=/vendor/libpam/dist/; revision=76238
-rw-r--r--contrib/libpam/CHANGELOG329
-rw-r--r--contrib/libpam/Make.Rules.in94
-rw-r--r--contrib/libpam/Makefile328
-rw-r--r--contrib/libpam/README167
-rw-r--r--contrib/libpam/_pam_aconf.h.in64
-rw-r--r--contrib/libpam/bin/README11
-rw-r--r--contrib/libpam/conf/Makefile28
-rwxr-xr-xcontrib/libpam/conf/md5itall4
-rw-r--r--contrib/libpam/conf/pam.conf74
-rw-r--r--contrib/libpam/conf/pam_conv1/README2
-rw-r--r--contrib/libpam/conf/pam_conv1/pam_conv.lex4
-rw-r--r--contrib/libpam/conf/pam_conv1/pam_conv.y4
-rwxr-xr-xcontrib/libpam/configure3548
-rw-r--r--contrib/libpam/configure.in339
-rw-r--r--contrib/libpam/defs/debian.defs40
-rw-r--r--contrib/libpam/defs/linux.defs4
-rw-r--r--contrib/libpam/defs/morgan.defs1
-rw-r--r--contrib/libpam/defs/redhat.defs4
-rw-r--r--contrib/libpam/defs/redhat4.defs35
-rw-r--r--contrib/libpam/defs/solaris-2.1.5.defs45
-rw-r--r--contrib/libpam/defs/suse.defs36
-rw-r--r--contrib/libpam/doc/CREDITS14
-rw-r--r--contrib/libpam/doc/Makefile88
-rw-r--r--contrib/libpam/doc/html/index.html2
-rw-r--r--contrib/libpam/doc/man/pam.8124
-rw-r--r--contrib/libpam/doc/man/pam.conf.82
-rw-r--r--contrib/libpam/doc/man/pam.d.82
-rw-r--r--contrib/libpam/doc/man/pam_authenticate.32
-rw-r--r--contrib/libpam/doc/man/pam_chauthtok.32
-rw-r--r--contrib/libpam/doc/man/pam_close_session.32
-rw-r--r--contrib/libpam/doc/man/pam_end.32
-rw-r--r--contrib/libpam/doc/man/pam_fail_delay.32
-rw-r--r--contrib/libpam/doc/man/pam_open_session.32
-rw-r--r--contrib/libpam/doc/man/pam_setcred.32
-rw-r--r--contrib/libpam/doc/man/pam_start.32
-rw-r--r--contrib/libpam/doc/man/pam_strerror.314
-rw-r--r--contrib/libpam/doc/man/template-man2
-rw-r--r--contrib/libpam/doc/modules/README2
-rw-r--r--contrib/libpam/doc/modules/module.sgml-template4
-rw-r--r--contrib/libpam/doc/modules/pam_access.sgml108
-rw-r--r--contrib/libpam/doc/modules/pam_chroot.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_cracklib.sgml39
-rw-r--r--contrib/libpam/doc/modules/pam_deny.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_env.sgml24
-rw-r--r--contrib/libpam/doc/modules/pam_filter.sgml6
-rw-r--r--contrib/libpam/doc/modules/pam_ftp.sgml8
-rw-r--r--contrib/libpam/doc/modules/pam_group.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_issue.sgml120
-rw-r--r--contrib/libpam/doc/modules/pam_krb4.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_lastlog.sgml24
-rw-r--r--contrib/libpam/doc/modules/pam_limits.sgml38
-rw-r--r--contrib/libpam/doc/modules/pam_listfile.sgml6
-rw-r--r--contrib/libpam/doc/modules/pam_mail.sgml46
-rw-r--r--contrib/libpam/doc/modules/pam_mkhomedir.sgml83
-rw-r--r--contrib/libpam/doc/modules/pam_motd.sgml77
-rw-r--r--contrib/libpam/doc/modules/pam_nologin.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_permit.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_pwdb.sgml19
-rw-r--r--contrib/libpam/doc/modules/pam_radius.sgml6
-rw-r--r--contrib/libpam/doc/modules/pam_rhosts.sgml11
-rw-r--r--contrib/libpam/doc/modules/pam_rootok.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_securetty.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_tally.sgml191
-rw-r--r--contrib/libpam/doc/modules/pam_time.sgml4
-rw-r--r--contrib/libpam/doc/modules/pam_unix.sgml288
-rw-r--r--contrib/libpam/doc/modules/pam_userdb.sgml112
-rw-r--r--contrib/libpam/doc/modules/pam_warn.sgml2
-rw-r--r--contrib/libpam/doc/modules/pam_wheel.sgml13
-rw-r--r--contrib/libpam/doc/pam_appl.sgml292
-rw-r--r--contrib/libpam/doc/pam_modules.sgml185
-rw-r--r--contrib/libpam/doc/pam_source.sgml280
-rw-r--r--contrib/libpam/doc/ps/README2
-rw-r--r--contrib/libpam/doc/specs/draft-morgan-pam.raw702
-rw-r--r--contrib/libpam/doc/txts/README2
-rw-r--r--contrib/libpam/examples/Makefile42
-rw-r--r--contrib/libpam/examples/blank.c19
-rw-r--r--contrib/libpam/examples/check_user.c9
-rw-r--r--contrib/libpam/examples/test.c13
-rw-r--r--contrib/libpam/examples/vpass.c2
-rw-r--r--contrib/libpam/examples/xsh.c54
-rw-r--r--contrib/libpam/libpam/Makefile108
-rw-r--r--contrib/libpam/libpam/include/security/_pam_compat.h29
-rw-r--r--contrib/libpam/libpam/include/security/_pam_macros.h54
-rw-r--r--contrib/libpam/libpam/include/security/_pam_types.h76
-rw-r--r--contrib/libpam/libpam/include/security/pam_appl.h25
-rw-r--r--contrib/libpam/libpam/include/security/pam_malloc.h8
-rw-r--r--contrib/libpam/libpam/include/security/pam_modules.h24
-rw-r--r--contrib/libpam/libpam/pam_account.c14
-rw-r--r--contrib/libpam/libpam/pam_auth.c21
-rw-r--r--contrib/libpam/libpam/pam_data.c88
-rw-r--r--contrib/libpam/libpam/pam_delay.c16
-rw-r--r--contrib/libpam/libpam/pam_dispatch.c109
-rw-r--r--contrib/libpam/libpam/pam_end.c14
-rw-r--r--contrib/libpam/libpam/pam_env.c49
-rw-r--r--contrib/libpam/libpam/pam_handlers.c162
-rw-r--r--contrib/libpam/libpam/pam_item.c180
-rw-r--r--contrib/libpam/libpam/pam_log.c92
-rw-r--r--contrib/libpam/libpam/pam_malloc.c37
-rw-r--r--contrib/libpam/libpam/pam_map.c3
-rw-r--r--contrib/libpam/libpam/pam_misc.c65
-rw-r--r--contrib/libpam/libpam/pam_password.c18
-rw-r--r--contrib/libpam/libpam/pam_private.h52
-rw-r--r--contrib/libpam/libpam/pam_second.c3
-rw-r--r--contrib/libpam/libpam/pam_session.c28
-rw-r--r--contrib/libpam/libpam/pam_start.c35
-rw-r--r--contrib/libpam/libpam/pam_static.c32
-rw-r--r--contrib/libpam/libpam/pam_strerror.c17
-rw-r--r--contrib/libpam/libpam/pam_tokens.h9
-rw-r--r--contrib/libpam/libpam_misc/Makefile139
-rw-r--r--contrib/libpam/libpam_misc/help_env.c9
-rw-r--r--contrib/libpam/libpam_misc/include/security/pam_misc.h57
-rw-r--r--contrib/libpam/libpam_misc/misc_conv.c100
-rw-r--r--contrib/libpam/libpam_misc/xstrdup.c9
-rw-r--r--contrib/libpam/libpamc/License42
-rw-r--r--contrib/libpam/libpamc/Makefile107
-rw-r--r--contrib/libpam/libpamc/include/security/pam_client.h190
-rw-r--r--contrib/libpam/libpamc/libpamc.h63
-rw-r--r--contrib/libpam/libpamc/pamc_client.c189
-rw-r--r--contrib/libpam/libpamc/pamc_converse.c211
-rw-r--r--contrib/libpam/libpamc/pamc_load.c477
-rwxr-xr-xcontrib/libpam/libpamc/test/agents/secret@here308
-rw-r--r--contrib/libpam/libpamc/test/modules/Makefile9
-rw-r--r--contrib/libpam/libpamc/test/modules/pam_secret.c670
-rw-r--r--contrib/libpam/libpamc/test/regress/Makefile7
-rwxr-xr-xcontrib/libpam/libpamc/test/regress/run_test.sh6
-rw-r--r--contrib/libpam/libpamc/test/regress/test.libpamc.c342
-rwxr-xr-xcontrib/libpam/libpamc/test/regress/test.secret@here152
-rw-r--r--contrib/libpam/modules/Makefile90
-rw-r--r--contrib/libpam/modules/README2
-rw-r--r--contrib/libpam/modules/Simple.Rules92
-rw-r--r--contrib/libpam/modules/dont_makefile4
-rwxr-xr-xcontrib/libpam/modules/download-all30
-rwxr-xr-xcontrib/libpam/modules/install_conf49
-rw-r--r--contrib/libpam/modules/pam_access/Makefile110
-rw-r--r--contrib/libpam/modules/pam_access/README6
-rw-r--r--contrib/libpam/modules/pam_access/pam_access.c153
-rw-r--r--contrib/libpam/modules/pam_cracklib/Makefile104
-rw-r--r--contrib/libpam/modules/pam_cracklib/README18
-rw-r--r--contrib/libpam/modules/pam_cracklib/pam_cracklib.c433
-rw-r--r--contrib/libpam/modules/pam_deny/Makefile118
-rw-r--r--contrib/libpam/modules/pam_deny/README2
-rw-r--r--contrib/libpam/modules/pam_deny/pam_deny.c15
-rw-r--r--contrib/libpam/modules/pam_env/Makefile107
-rw-r--r--contrib/libpam/modules/pam_env/README6
-rw-r--r--contrib/libpam/modules/pam_env/pam_env.c186
-rw-r--r--contrib/libpam/modules/pam_env/pam_env.conf-example6
-rw-r--r--contrib/libpam/modules/pam_filter/Makefile64
-rw-r--r--contrib/libpam/modules/pam_filter/README2
-rw-r--r--contrib/libpam/modules/pam_filter/include/pam_filter.h4
-rw-r--r--contrib/libpam/modules/pam_filter/pam_filter.c18
-rw-r--r--contrib/libpam/modules/pam_filter/upperLOWER/Makefile33
-rw-r--r--contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c17
-rw-r--r--contrib/libpam/modules/pam_ftp/Makefile91
-rw-r--r--contrib/libpam/modules/pam_ftp/README26
-rw-r--r--contrib/libpam/modules/pam_ftp/pam_ftp.c52
-rw-r--r--contrib/libpam/modules/pam_group/Makefile113
-rw-r--r--contrib/libpam/modules/pam_group/group.conf2
-rw-r--r--contrib/libpam/modules/pam_group/pam_group.c41
-rw-r--r--contrib/libpam/modules/pam_issue/Makefile15
-rw-r--r--contrib/libpam/modules/pam_issue/pam_issue.c266
-rw-r--r--contrib/libpam/modules/pam_lastlog/Makefile101
-rw-r--r--contrib/libpam/modules/pam_lastlog/pam_lastlog.c17
-rw-r--r--contrib/libpam/modules/pam_limits/Makefile101
-rw-r--r--contrib/libpam/modules/pam_limits/README35
-rw-r--r--contrib/libpam/modules/pam_limits/limits.skel1
-rw-r--r--contrib/libpam/modules/pam_limits/pam_limits.c246
-rw-r--r--contrib/libpam/modules/pam_listfile/Makefile81
-rw-r--r--contrib/libpam/modules/pam_listfile/pam_listfile.c103
-rw-r--r--contrib/libpam/modules/pam_mail/Makefile102
-rw-r--r--contrib/libpam/modules/pam_mail/README17
-rw-r--r--contrib/libpam/modules/pam_mail/pam_mail.c246
-rw-r--r--contrib/libpam/modules/pam_mkhomedir/Makefile15
-rw-r--r--contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c370
-rw-r--r--contrib/libpam/modules/pam_motd/Makefile15
-rw-r--r--contrib/libpam/modules/pam_motd/pam_motd.c119
-rw-r--r--contrib/libpam/modules/pam_nologin/Makefile83
-rw-r--r--contrib/libpam/modules/pam_nologin/README2
-rw-r--r--contrib/libpam/modules/pam_nologin/pam_nologin.c16
-rw-r--r--contrib/libpam/modules/pam_permit/Makefile119
-rw-r--r--contrib/libpam/modules/pam_permit/README2
-rw-r--r--contrib/libpam/modules/pam_permit/pam_permit.c12
-rw-r--r--contrib/libpam/modules/pam_pwdb/BUGS7
-rw-r--r--contrib/libpam/modules/pam_pwdb/CHANGELOG2
-rw-r--r--contrib/libpam/modules/pam_pwdb/Makefile91
-rw-r--r--contrib/libpam/modules/pam_pwdb/README4
-rw-r--r--contrib/libpam/modules/pam_pwdb/TODO2
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5.c26
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5.h20
-rw-r--r--contrib/libpam/modules/pam_pwdb/md5_crypt.c72
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_pwdb.c55
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c24
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c46
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_md.-c20
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c60
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c14
-rw-r--r--contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c18
-rw-r--r--contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c39
-rw-r--r--contrib/libpam/modules/pam_pwdb/support.-c132
-rw-r--r--contrib/libpam/modules/pam_radius/Makefile12
-rw-r--r--contrib/libpam/modules/pam_radius/pam_radius.h9
-rw-r--r--contrib/libpam/modules/pam_rhosts/Makefile103
-rw-r--r--contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c56
-rw-r--r--contrib/libpam/modules/pam_rootok/Makefile106
-rw-r--r--contrib/libpam/modules/pam_rootok/README2
-rw-r--r--contrib/libpam/modules/pam_rootok/pam_rootok.c17
-rw-r--r--contrib/libpam/modules/pam_securetty/Makefile80
-rw-r--r--contrib/libpam/modules/pam_securetty/pam_securetty.c63
-rw-r--r--contrib/libpam/modules/pam_shells/Makefile81
-rw-r--r--contrib/libpam/modules/pam_shells/pam_shells.c18
-rw-r--r--contrib/libpam/modules/pam_stress/Makefile104
-rw-r--r--contrib/libpam/modules/pam_stress/README2
-rw-r--r--contrib/libpam/modules/pam_stress/pam_stress.c30
-rw-r--r--contrib/libpam/modules/pam_tally/Makefile54
-rw-r--r--contrib/libpam/modules/pam_tally/README52
-rw-r--r--contrib/libpam/modules/pam_tally/faillog.h55
-rw-r--r--contrib/libpam/modules/pam_tally/pam_tally.c150
-rw-r--r--contrib/libpam/modules/pam_tally/pam_tally_app.c7
-rw-r--r--contrib/libpam/modules/pam_time/Makefile120
-rw-r--r--contrib/libpam/modules/pam_time/README9
-rw-r--r--contrib/libpam/modules/pam_time/pam_time.c29
-rw-r--r--contrib/libpam/modules/pam_unix/CHANGELOG57
-rw-r--r--contrib/libpam/modules/pam_unix/Makefile168
-rw-r--r--contrib/libpam/modules/pam_unix/README58
-rw-r--r--contrib/libpam/modules/pam_unix/bigcrypt.c119
-rw-r--r--contrib/libpam/modules/pam_unix/lckpwdf.-c117
-rw-r--r--contrib/libpam/modules/pam_unix/md5.c256
-rw-r--r--contrib/libpam/modules/pam_unix/md5.h31
-rw-r--r--contrib/libpam/modules/pam_unix/md5_crypt.c149
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_acct.c195
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_auth.c347
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_passwd.c1615
-rw-r--r--contrib/libpam/modules/pam_unix/pam_unix_sess.c214
-rw-r--r--contrib/libpam/modules/pam_unix/support.c958
-rw-r--r--contrib/libpam/modules/pam_unix/support.h144
-rw-r--r--contrib/libpam/modules/pam_unix/unix_chkpwd.c314
-rw-r--r--contrib/libpam/modules/pam_unix/yppasswd.h51
-rw-r--r--contrib/libpam/modules/pam_unix/yppasswd_xdr.c38
-rw-r--r--contrib/libpam/modules/pam_userdb/Makefile35
-rw-r--r--contrib/libpam/modules/pam_userdb/README30
-rw-r--r--contrib/libpam/modules/pam_userdb/conv.c125
-rw-r--r--contrib/libpam/modules/pam_userdb/create.pl23
-rw-r--r--contrib/libpam/modules/pam_userdb/pam_userdb.c304
-rw-r--r--contrib/libpam/modules/pam_userdb/pam_userdb.h61
-rw-r--r--contrib/libpam/modules/pam_warn/Makefile91
-rw-r--r--contrib/libpam/modules/pam_warn/README7
-rw-r--r--contrib/libpam/modules/pam_warn/pam_warn.c56
-rw-r--r--contrib/libpam/modules/pam_wheel/Makefile89
-rw-r--r--contrib/libpam/modules/pam_wheel/pam_wheel.c32
248 files changed, 17868 insertions, 6414 deletions
diff --git a/contrib/libpam/CHANGELOG b/contrib/libpam/CHANGELOG
index 99872a4704c7..162625b07b24 100644
--- a/contrib/libpam/CHANGELOG
+++ b/contrib/libpam/CHANGELOG
@@ -1,24 +1,329 @@
-$Id$
+$Id: CHANGELOG,v 1.61 2001/04/08 06:17:04 agmorgan Exp $
-----------------------------
-0.66: whenever
+TODO:
-TODO
- - need to supply a backward compatability path for syslog & friends
- - need to make pam_system_log() thread safe.
- - need to make logging fix available to non-Linux PAM libraries
- - need to change modules to make use of new logging API.
+ - sanitize use of md5 throughout distribution.. Make a static
+ library for helping to develop modules that contains it and other
+ stuff. Also add sha-1 and ripemd-160 digest algorithms.
+ - once above is done. remove hacks from the secret@here module etc..
+ - remove prototype for gethostname in pam_access.c (Derrick)
- document PAM_INCOMPLETE changes
- - document pam_system_log() changes
- verify that the PAM_INCOMPLETE interface is sensible. Can we
- catch errors? should we permit item changing etc between
+ catch errors? should we permit item changing etc., between
pam_authenticate re-invocations?
- - verify that the PAM_INCOMPLETE interface works
- - add PAM_INCOMPLETE support to modules
- - verify that
+ - verify that the PAM_INCOMPLETE interface works (auth seems ok..)
+ - add PAM_INCOMPLETE support to modules (partially added to pam_pwdb)
- work on RFC.
+ - do we still need to remove openlog/closelog from modules..?
+ - auth and acct support in pam_cracklib, "yes, I know the password
+ you just typed was valid, I just don't think it was very strong..."
+ - add in the pam_cap and pam_netid modules
+
+====================================================================
+Note, as of release 0.73, all checkins should be accompanied with a
+Bug ID. The bug IDs relate to sourceforge IDs.. You can query the
+related bug description with the following URL:
+
+ http://sourceforge.net/tracker/index.php?func=detail&aid=XXXXXX&group_id=6663&atid=106663
+
+Where you should replace XXXXXX with a bug-id.
+
+If you have found a bug in Linux-PAM, please consider filing such a
+bug report - outstanding bugs are listed here:
+
+ http://sourceforge.net/tracker/?atid=106663&group_id=6663&func=browse
+
+(to file another bug see the 'submit bug' button on this page).
+
+====================================================================
+
+0.76: please submit patches for this section with actual code/doc
+ patches!
+
+*
+
+0.75: Sat Apr 7 23:10:50 PDT 2001
+
+ ** WARNING **
+
+This release contains backwardly incompatible changes to
+libpam. Prior versions were buggy - see bugfix for Bug 129775.
+
+ ** WARNING **
+
+* made 0.75 release (Bug 414665 - agmorgan)
+* pam_pwdb has been removed from the suggested pam.conf template. I've
+ replaced it with pam_unix. (Bug 227565 - agmorgan)
+* pam_limits - Richard M. Yumul reported that "<domain> -" didn't
+ work, first fix suggested by Werner Puschitz (Bug 404953 - agmorgan)
+* Nicolay Pelov suggested a simple fix for freebsd support (Bug 407282
+ - agmorgan)
+* Michel D'HOOGE submitted documentation fixes (Bug 408961 - agmorgan)
+* fix for module linking directions (Bug 133545 - agmorgan)
+* fix for glibc-2.2.2 compilation of pam_issue (Bug 133542 - agmorgan)
+* fix pam_userdb to make and link both .o files it needs - converse()
+ wasn't being linked! (Bug 132880 - agmorgan)
+* added some sys-admin documentation for the pam_tally module (Bug
+ 126210 - agmorgan).
+* added a link to module examples from the module writers doc (Bug
+ 131192 - agmorgan).
+* fixed a small security hole (more of a user confusion issue) with
+ the unix and pwdb password helper binaries. The beef is described in
+ the bug report, but no uid change was possible so no-one should
+ think they need to issue a security bulletin over this one! (Bug
+ 112540 - agmorgan)
+* pam_lastlog needs to be linked with -lutil, also removed ambiguity
+ from sysadmin guide regarding this module being a 'session' module
+ (Bug 131549 - agmorgan).
+* pam_cracklib needs to be linked with -lcrypt (old password checking)
+ (Bug 131601 - agmorgan).
+* fixes for static library builds and also the examples when linked
+ with the debugging build of the libraries. (Bug 131783 - agmorgan)
+* fixed URL for original RFC to a cached kernel.org file. (Bug 131503
+ - agmorgan)
+* quoted the $CRACKLIB_DICTPATH test in configure.in (Bug 130130 -
+ agmorgan).
+* improved handling of the setcred/close_session and update chauthtok
+ stack. *Warning* This is a backwardly incompatable change, but 'more
+ sane' than before. (Bug 129775 - agmorgan)
+* bumped the version number, and added some code to assist in making
+ documentation releases (Bug 129644 - agmorgan).
+
+0.74: Sun Jan 21 22:36:08 PST 2001
+
+* made 0.74 release (Bug 129642 - agmorgan)
+* libpam - cleaned up a few non-static functions to be static and added
+ support for libpam to enforce things like pam_[gs]et_data() and
+ AUTHTOK rules for using the API. Also documented pam_[gs]et_item()
+ a little better including return codes (Bugs 129027, 128576 -
+ agmorgan).
+* pam_access - fixed the non-default config file option (Bug 127561 -
+ agmorgan)
+* pam.8 manual page clarified with respect to the default location for
+ finding modules, also added some text describing the [...] control
+ syntax. (Bug 127625 - agmorgan)
+* md5.h ia64 fixes for pam_unix and pam_pwdb (Bug 127700 - agmorgan)
+* removed requirement for c++ from the configure{.in,} files (Bug
+ 128298 - agmorgan)
+* removed subdirectories from man page redirections (124396 - baggins)
+* per David Lee, fixed non-POSIX shell command in modules/pam_filter/Makefile
+ (Bug 126440 - vorlon)
+* modify format of pam_unix log messages to include service name
+ (Bug 126423 - vorlon)
+* prevent pam_unix from logging unknown usernames (Bug 126431 - vorlon)
+* changed format of pam_unix 'authentication failure' log messages to make
+ them clearer and more consistent (Bug 126036 - vorlon)
+* improved portability of pam_unix by eliminating Linux-specific utmp
+ defines in PAM_getlogin() (Bug 125704 - vorlon)
+* removed static variables from pam_tally (Bug 117434 - agmorgan)
+* added copyright message to pam_access module from original logdaemon
+ sources (Bug 125022 - agmorgan)
+* configure.in - removed the GCC -Wtraditional flag (Bug 124923 - agmorgan)
+* pam_mail - use PAM_PATH_MAILDIR as the location of mail spool
+ (Bug 124397 - baggins)
+* _pam_aconf.h.in, configure.in - added PAM_PATH_MAILDIR set via
+ --with-mailspool=dir option (default is _PAM_MAILDIR if defined
+ in paths.h otherwise /var/spool/mail (Bug 124397 - baggins)
+* removed unnecessary CVS Log tags from all over the source
+ (Bug 124391 - baggins)
+* pam_tally - check for PAM_TTY if PAM_RHOST is not set when writing
+ to faillog (Bug 124394 - baggins)
+* use O_NOFOLLOW if available when opening debug log (Bug 124385 - baggins)
+* pam_cracklib - removed comments about pam_unix not working with
+ pam_cracklib, added information about use_authtok parameter
+ (Bug 124388 - baggins)
+* pam_userdb - fixed wrong definition of struct pam_module (was pam_wheel)
+ (Bug 124386 - baggins)
+* fixed example/Makefile include path (Bug 124187, 127563(?) - agmorgan)
+* pam_userdb compiles on RH5x. Also removed circular dependency on
+ configure.in. Also bumped revision number to 0.74. (Bug 124136 -
+ agmorgan)
+
+0.73: Sat Dec 2 00:04:04 PST 2000
+
+* updated documentaion revisions and added 'make release' support
+ to the top level Makefile (Bug 124132 - agmorgan).
+* documented Qmail support in pam_mail (Bug 109219 - baggins)
+* add change_uid option to pam_limits, and set real uid only if
+ this option is present (Bug 124062 - baggins)
+* pam_limits - set real uid to the user for who we set limits.
+ (Bug 123972 - baggins)
+* removed static variables from pam_limits (thread safe now). (Bug
+ 117450 - agmorgan).
+* removed static variable from pam_wheel (module should be thread safe
+ now). (Bug 112906 - agmorgan)
+* added support for '/' symbols in pam_time and pam_group config files
+ (support for modern terminal devices). Fixed infinite loop problem
+ with '\\[^\n]' in these files. (Bug 116076 - agmorgan)
+* avoid potential SIGPIPE when writing to helper binaries with (Bug
+ 123399 - agmorgan)
+* replaced bogus logic in the pam_cracklib module for determining if
+ the replacement is too similar to the old password (Bug 115055 -
+ agmorgan)
+* added accessconf=<filename> feature to pam_access - request from
+ Aldrin Martoq and Meelis Roos (Bugs 111927,117240 - agmorgan)
+* fix for pam_limit module not dealing with all limits Adam J. Richter
+ (Bug 119554 - agmorgan)
+* comment fix describing fail_delay callback in _pam_types.h (Bug
+ 112646 - agmorgan)
+* "likeauth" fix for pam_unix and pam_pwdb which (Bug 113596 - agmorgan)
+* fix for pam_unix (support.c) to avoid segfault with NULL password
+ (Bug 113238 - vorlon)
+* fix to pam_unix_passwd: try repeatedly to get a lock on the password
+ file, instead of failing immediately (Bug 108845 - fix vorlon)
+* fix to pam_shells: logged information was not formatted correctly
+ (extra comma) (Bug 111491 - fix vorlon)
+* fix for C++ application support (Bug 111645 - fix agmorgan)
+* fix for typo in pam_client.h (Bug 111648 - fix agmorgan)
+* removal of -lpam from pam_mkhomedir Makefile (Bug 116380 - fix agmorgan)
+* autoconf support [Task ID 15788, Bug ID 108297 - agmorgan with help!]
+ - bugfix for libpamc.h include file [Bug ID 117476 - agmorgan]
+ - bugfix for pam_filter.h inclusion [Bug ID 117474 - agmorgan]
+
+0.72: Mon Dec 13 22:41:11 PST 1999
+
+* patches from Debian (Ben Collins): pam_ftp supports event driven
+ conversations now; pwdb_chkpwd cleanup; pam_warn static compile fix;
+ user_db compiler warnings removed; debian defs file; pam_mail can
+ now be used as a session module
+* ndbm compilation option for user_db module (fix explained by Richard Khoo)
+* pam_cracklib bug fix
+* packaging fixes & build from scratch stuff (Konst Bulatnikov & Frodo
+ Looijaard)
+* -ldl appended to the libpam.so compilation make rule. (Charles Seeger)
+* Red Hat security patch for pam_pwdb forwarded by Debian! (Ben
+ Collins. Fix provided by Andrey as it caught the problem earlier in the
+ code.)
+* heuristic to prevent leaking filedescriptors to an agent. [This needs
+ to be better supported perhaps by an additional libpamc API function?]
+* pam_userdb segfault fix from (Ben Collins)
+* PAM draft spec extras added at request of 'sen_ml'
+
+0.71: Sun Nov 7 20:21:19 PST 1999
+
+* added -lc to linker pass for pam_nologin module (glibc is weird).
+* various header changes to lower the number of warnings on glibc
+ systems (Dan Yefimov)
+* merged a bunch of Debian fixes/patches/documentation (Ben Collins)
+ things touched: libpam (minor); doc/modules/pam_unix.sgml; pam_env
+ (plus docs); pam_mkhomedir (new module for new home directories on
+ the fly...); pam_motd (new module); pam_limits (adjust to match
+ docs); pam_issue (new module + doc) [Some of these were also
+ submitted by Thorsten Kukuk]
+* small hack to lower the number of warnings that pam_client.h was
+ generating.
+* debian and SuSE apparently can use the pam_ftp module, so
+ removed the obsolete comment about this from the docs. (Thorsten
+ Kukuk)
+
+0.70: Fri Oct 8 22:05:30 PDT 1999
+
+* bug fix for parsing of value=action tokens in libpam/pam_misc.c was
+ segfaulting (Jan Rekorajski and independently Matthew Melvin)
+* numerous fixes from Thorsten Kukuk (icluding much needed fixes for
+ bitrot in modules and some documentation) that got included in SuSE 6.2.
+* reentrancy issues in pam_unix and pam_cracklib resolved (Jan Rekorajski)
+* added hosts_equiv_rootok module option to pam_rhosts module (Tim Berger)
+* added comment about 'expose_account' module argument to admin and
+ module writers' docs (request from Michael K Johnson).
+* myriad of bug fixes for libpamc - library now built by default and
+ works with the biomouse fingerprint scanner agent/module
+ (distributed separately).
+
+0.69: Sun Aug 1 20:25:37 PDT 1999
+
+* c++ header #ifdef'ing for pam_appl.h (Tuomo Pyhala)
+* added pam_userdb module (Cristian Gafton)
+* minor documentation changes
+* added in revised pam_client library (libpamc). Not installed by
+ default yet, since the example agent/module combo is not very secure.
+* glibc fixes (Thorsten Kukuk, Adam J. Richter)
+
+0.68: Sun Jul 4 23:04:13 PDT 1999
+
+* completely new pam_unix module from Jan Rekorajski and Stephen Langasek
+* Jan Rekorajski pam_mail - support for Maildir format mailboxes
+* Jan Rekorajski pam_cracklib - support for old password comparison
+* Jan Rekorajski bug fix for pam_pwdb setcred reusing auth retval
+* Andrey's pam_tally patch (lstat -> fstat)
+* Robert Milkowski's additional pam_tally patches to **change format of
+ /var/log/faillog** to one from shadow-utils, add new option "per_user"
+ for pam_tally module, failure time logging, support for fail_line
+ field, and support for fail_locktime field with new option
+ no_lock_time.
+* pam_tally: clean up the tally application too.
+* Marcin Korzonek added process priority settings to pam_limits (bonus
+ points for adding to documentation!)
+* Andrey's pam_pwdb patch (cleanup + md5 endian fubar fix)
+* more binary prompt preparations (make misc conv more compatible with spec)
+* modified callback hook for fail delay to be more useful with event
+ driven applications (changed function prototype - suspect no one
+ will notice). Documented this in app developer guide.
+* documentation for pam_access from Tim Berger
+* syntax fixes for the documentation - a long time since I've built it :*(
+ added some more names to the CREDITS file.
+
+0.67: Sat Jun 19 14:01:24 PDT 1999
+
+* [dropped libpam_client - libpamc will be in the next release and
+ conforms to the developing spec in doc/specs/draft-morgan-pam.raw.
+ Sorry if you are keeping a PAM tree in CVS. CVS is a pain for
+ directories, but this directory was actually not referenced by
+ anything so the disruption should be light.]
+* updates to pam_tally from Tim
+* multiple updates from Stephen Langasek to pam_unix
+* pam_filter had some trouble compiling (bug report from Sridhar)
+* pam_wheel now attempts to identify the wheel group for the local
+ system instead of blindly assuming it is gid=0. In the case that
+ there is no "wheel" group, we default to assuming gid=0 is what was
+ meant - former behavior. (courtesy of Sridhar)
+* NIS+ changes to pam_unix module from Dmitry O Panov
+* hopefully, a fix for redefinition of LOG_AUTHPRIV (bug report Luke
+ Kenneth Casson Leighton)
+* fix for minor typo in pam_wheel documentation (Jacek Kopecky)
+* slightly more explanation of the [x=y] pam.conf syntax in the sys
+ admin guide.
+
+0.66: Mon Dec 28 20:22:23 PST 1998 <morgan@linux.kernel.org>
+
+* Started using cvs to keep track of changes to Linux-PAM. This will
+ likely break some of the automated building stuff (RPMs etc..).
+* security bug fix to pam_unix and pam_tally from Andrey.
+* modules make file is now more automatic. It should be possible to
+ unpack an external module in the modules directory and have it automatically
+ added to the build process. Also added a modules/download-all script
+ that will make such downloading easier. I'm happy to receive patches to
+ this file, informing the distribution of places from which to enrich itself.
+* removed pam_system_log stuff. Thought about it long and hard: a
+ bad idea. If libc cannot guarantee a thread safe syslog, it needs
+ to be fixed and compatibility with other PAM libraries was
+ unnecessarily strained.
+* SAG documentation changes: Seth Chaiklin
+* rhosts: problems with NIS lookup failures with the root-uid check.
+ As a work-around, I've partially eliminated the need for the lookup
+ by supplying two new arguments: no_uid_check, superuser=<username>.
+ As a general rule this is more pluggable, since this module might be
+ used as an authentication scheme for a network service that does not
+ need root privilege...
+* authenticate retval -> setcred for pam_pwdb (likeauth arg).
+* pam_pwdb event driven support
+* non openlog pam_listfile logging
+* BUGFIX: close filedescriptor in pam_group and pam_time (Emmanuel Galanos)
+* Chris Adams' mailhash change for pam_mail module
+* fixed malloc failure check in pam_handlers.c (follow up to comment
+ by Brad M. Garcia).
+* update to _pam_compat.h (Brad M. Garcia)
+* support static modules in libpam again (Brad M. Garcia)
+* libpam/pam_misc.c for egcs to grok the code (Brad M. Garcia)
+* added a solaris-2.5.1 defs file (revived by Derrick J Brashear)
+* pam_listfile logs failed attempts
+* added a comment (Michael K Johnson pointed it out) about sgml2latex
+ having a new syntax. I'll make it the change real when I upgrade...
+* a little more text to the RFC, spelling fix from William J Buffam.
+* minor changes to pam_securetty to accommodate event driven support.
0.65: Sun Apr 5 22:29:09 PDT 1998 <morgan@linux.kernel.org>
diff --git a/contrib/libpam/Make.Rules.in b/contrib/libpam/Make.Rules.in
new file mode 100644
index 000000000000..2818c1c97db1
--- /dev/null
+++ b/contrib/libpam/Make.Rules.in
@@ -0,0 +1,94 @@
+##
+## $Id: Make.Rules.in,v 1.6 2001/02/10 22:33:09 agmorgan Exp $
+##
+## @configure_input@
+##
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+VPATH = @srcdir@
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+
+bindir = @bindir@
+sbindir = @sbindir@
+libexecdir = @libexecdir@
+datadir = @datadir@
+sysconfdir = @sysconfdir@
+sharedstatedir = @sharedstatedir@
+localstatedir = @localstatedir@
+libdir = @libdir@
+infodir = @infodir@
+mandir = @mandir@
+includedir = @includedir@
+
+absolute_srcdir = @LOCALSRCDIR@
+
+# major and minor numbers of this release
+MAJOR_REL=@LIBPAM_VERSION_MAJOR@
+MINOR_REL=@LIBPAM_VERSION_MINOR@
+
+# The following is the generic set of compiler options for compiling
+# Linux-PAM. True, they are a little anal. Pay attention to the comments
+# they generate.
+
+HEADER_DIRS=-I./include -I$(absolute_srcdir)/libpam/include \
+ -I$(absolute_srcdir) -I$(absolute_srcdir)/libpamc/include
+WARNINGS=@WARNINGS@
+OS_CFLAGS=@OS_CFLAGS@
+PIC=@PIC@
+
+# Mode to install shared libraries with
+SHLIBMODE=@SHLIBMODE@
+
+NEED_LINK_LIB_C=@PAM_NEEDS_LIBC@
+HAVE_LCKPWDF=@HAVE_LCKPWDF@
+HAVE_LIBCRACK=@HAVE_LIBCRACK@
+HAVE_LIBCRYPT=@HAVE_LIBCRYPT@
+HAVE_LIBUTIL=@HAVE_LIBUTIL@
+HAVE_NDBM_H=@HAVE_NDBM_H@
+HAVE_LIBNDBM=@HAVE_LIBNDBM@
+HAVE_LIBDB=@HAVE_LIBDB@
+HAVE_LIBFL=@HAVE_LIBFL@
+HAVE_LIBNSL=@HAVE_LIBNSL@
+HAVE_LIBPWDB=@HAVE_LIBPWDB@
+
+# documentation support
+HAVE_SGML2TXT=@HAVE_SGML2TXT@
+HAVE_SGML2HTML=@HAVE_SGML2HTML@
+PSER=@PSER@
+
+# configuration settings
+WITH_DEBUG=@WITH_DEBUG@
+WITH_LIBDEBUG=@WITH_LIBDEBUG@
+WITH_PAMLOCKING=@WITH_PAMLOCKING@
+WITH_LCKPWDF=@WITH_LCKPWDF@
+STATIC_LIBPAM=@STATIC_LIBPAM@
+DYNAMIC_LIBPAM=@DYNAMIC_LIBPAM@
+STATIC=@STATIC@
+DYNAMIC=@DYNAMIC@
+
+# Location of libraries when installed on the system
+FAKEROOT=@FAKEROOT@
+SECUREDIR=@SECUREDIR@
+SCONFIGD=@SCONFIGDIR@
+SUPLEMENTED=@SUPLEMENTED@
+INCLUDED=@INCLUDEDIR@/security
+CRACKLIB_DICTPATH=@CRACKLIB_DICTPATH@
+
+# generic build setup
+OS=@OS@
+CC=@CC@
+CFLAGS=$(WARNINGS) -D$(OS) $(OS_CFLAGS) $(HEADER_DIRS) @CONF_CFLAGS@
+LD=@LD@
+LD_D=@LD_D@
+LD_L=@LD_L@
+DYNTYPE=@DYNTYPE@
+LIBDL=@LIBDL@
+MKDIR=@MKDIR@
+INSTALL=@INSTALL@
+RANLIB=@RANLIB@
+STRIP=@STRIP@
+CC_STATIC=@CC_STATIC@
+
+LINKLIBS = $(NEED_LINK_LIB_C) $(LIBDL)
diff --git a/contrib/libpam/Makefile b/contrib/libpam/Makefile
index d25f58bb570e..ad2eea2edc29 100644
--- a/contrib/libpam/Makefile
+++ b/contrib/libpam/Makefile
@@ -1,282 +1,78 @@
##
-## $Id: Makefile,v 1.31 1997/04/05 07:04:25 morgan Exp morgan $
+## $Id: Makefile,v 1.5 2001/01/20 22:29:47 agmorgan Exp $
##
-## $Log: Makefile,v $
-##
-##
-
-# major and minor numbers of this release
-MAJOR_REL=0
-MINOR_REL=65
-DEBUG_REL=no
-#DEBUG_REL=yes
-
-# this should be the name of this directory
-RELNAME = Linux-PAM-$(MAJOR_REL).$(MINOR_REL)
-
-# this is the name of the archive file
-DISTFILE = $(RELNAME).tar.gz
-
-# define this to indicate to subdirectories that they are part of the
-# full source tree.
-FULL_LINUX_PAM_SOURCE_TREE=yes
-export FULL_LINUX_PAM_SOURCE_TREE
-
-DYNLOAD="dl"
-DYNTYPE="so"
-
-# Comment out either line to disable that type of linking for *modules only*
-# Both at once is a legal configuration!
-DYNAMIC=-DPAM_DYNAMIC
-#STATIC=-DPAM_STATIC
-
-# Comment out these lines to disable building dynamic/static libpam.*
-DYNAMIC_LIBPAM=yes
-#STATIC_LIBPAM=yes
-
-# All combinations of the above four variable definitions are legal,
-# however, not defining either dynamic or static modules and yet
-# creating a some flavor of LIBPAM will make an authentication library
-# that always fails!
-
-# Here we indicate which libraries are present on the local system
-# they control the building of some modules in this distribution
-# Note, these definitions are all "export"ed below...
-
-HAVE_PWDBLIB=no
-HAVE_CRACKLIB=no
-HAVE_AFSLIBS=no
-HAVE_KRBLIBS=no
-
-# NB. The following is the generic defines for compilation.
-# They can be overridden in the default.defs file below
-#
-WARNINGS = -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align \
- -Wtraditional -Wstrict-prototypes -Wmissing-prototypes \
- -Wnested-externs -Winline -Wshadow -pedantic
-PIC=-fPIC
-# Mode to install shared libraries with
-SHLIBMODE=644
+## Note, ideally I would prefer it if this top level makefile did
+## not get created by autoconf. As I find typing 'make' and relying
+## on it to take care of all dependencies much more friendly than
+## the multi-stage autoconf+make and also worry about updates to
+## configure.in not getting propagated down the tree. (AGM) [I realise
+## that this may not prove possible, but at least I tried.. Sigh.]
-#
-# Conditional defines..
-#
+DISTNAME=Linux-PAM
-ifdef DYNAMIC
-# need the dynamic library functions
-LIBDL=-l$(DYNLOAD)
-ifdef STATIC_LIBPAM
-# needed because pam_xxx() fn's are now in statically linked library
-RDYNAMIC = -rdynamic
+ifeq ($(shell test \! -f Make.Rules || echo yes),yes)
+ include Make.Rules
endif
-endif
-
-# Here we include the defines for the preferred operating system
-# these include things like CC, CFLAGS and destination directories
-# etc.. By default, this is a symbolic link to one of the .defs files
-# the .../defs/ directory. Please take a moment to check that you are
-# using the correct one.
-
-include default.defs
-
-# to turn on the fprintf(stderr, ..) debugging lines throughout the
-# distribution uncomment this line
-#EXTRAS += -DDEBUG
-
-# For serious memory allocation tracing uncomment the following
-#MEMORY_DEBUG=-DMEMORY_DEBUG
-
-#######################################################################
-# The pam_unix module in this file will not work on NIS based systems.#
-#######################################################################
-
-# ////////////////////////////////////////////////////
-# // You should not modify anything below this line //
-# ////////////////////////////////////////////////////
-
-# the sub-directories to make things in
-
-DIRS = modules libpam conf libpam_misc examples
-
-#
-# basic defines
-#
-
-INCLUDEDIR=-I$(shell pwd)/include
-PAMLIB=-L$(shell pwd)/libpam
-PAMMISCLIB=-L$(shell pwd)/libpam_misc
-ifeq ($(DEBUG_REL),yes)
- PAMLIB += -lpamd
- PAMMISCLIB += -lpamd_misc
-else
- PAMLIB += -lpam
- PAMMISCLIB += -lpam_misc
-endif
-
-# This is Linux-PAM and not a version from Sun etc..
-# [Note, this does not describe the operating system you are using
-# only that you are compiling the "Linux" (read FREE) implementation
-# of Pluggable Authentication Modules.
-EXTRAS += -DLINUX_PAM
+THINGSTOMAKE = modules libpam libpamc libpam_misc doc examples
-#
-# build composite defines
-#
+all: $(THINGSTOMAKE)
-LOADLIBES = $(PAMLIB) $(RDYNAMIC) $(PAMMISCLIB) $(LIBDL) $(ULIBS)
-
-CFLAGS += $(EXTRAS) $(MEMORY_DEBUG) $(WARNINGS) $(INCLUDEDIR) $(PIC)
-ifneq ($(strip $(OS)),)
-CFLAGS += -D$(OS)
-endif
-ifneq ($(strip $(ARCH)),)
-CFLAGS += -D$(ARCH)
-endif
-
-#
-# export the libraries-available info; the modules should know how
-# to deal with this...
-#
-export HAVE_PWDBLIB
-export HAVE_CRACKLIB
-export HAVE_AFSLIBS
-export HAVE_KRBLIBS
-
-#
-# generic exports
-#
-export MAJOR_REL # the major release of this distribution
-export MINOR_REL # the minor release of this distribution
-export DEBUG_REL # for installing a debugging version of PAM
-export OS # operating system
-export ARCH # architecture
-export CC # the C compiler
-export INSTALL # to do instalations with
-export MKDIR # to ensure directories exist
-export CFLAGS # CC flags used to compile everything
-export LD_D # build a shared object file (module)
-export LD_L # build a shared library (e.g. libpam)
-export USESONAME # does shlib link command require soname option
-export SOSWITCH # shlib lib soname switch name
-export NEEDSONAME # does shared library link need versioned lib
-export LD # build a generic library
-export LDCONFIG # rebuild the shared libraries
-export AR # build a static library
-export RANLIB # reorder a static library
-export LOADLIBES # libraries needed for application linking
-export PAMLIB # where to find the local libpam.xx file
-export DYNTYPE # which suffix is used for libraries
-export SHLIBMODE # file mode for shared objects
-#
-# where to install things
-#
-export FAKEROOT # for package maintainers
-#
-export PREFIX # basic prefix for all other directories
-export SUPLEMENTED # where to store module helper binaries
-export LIBDIR # where libpam and libpam_misc go
-export SECUREDIR # where the modules will be placed
-export INCLUDED # where to store pam---.h files
-export CONFIGED # where pam.conf and pam.d/ go
-export SCONFIGED # where modules' config files go
-
-#
-# Conditional exporting ( ... these go on for a while... )
-#
-ifdef DYNAMIC
-export DYNAMIC
-endif
-ifdef STATIC
-export STATIC
-endif
-ifdef DYNAMIC_LIBPAM
-export DYNAMIC_LIBPAM
-endif
-ifdef STATIC_LIBPAM
-export STATIC_LIBPAM
-endif
-ifdef MEMORY_DEBUG
-export MEMORY_DEBUG
-endif
-
-##
-## the rules
-##
-
-all: .freezemake
- @for i in $(DIRS) ; do \
- $(MAKE) -C $$i all ; \
- if [ $$? -ne 0 ]; then break ; fi ; \
- done
-
-.freezemake:
-# Do nothing
-
-.old_freezemake: Makefile
- @touch .freezemake
- @echo "*WARNING*: If you are running a system that is dependent"
- @echo " on PAM to work. DO NOT make sterile NOR make remove."
- @echo " These options will delete the PAM files on your system"
- @echo " and make it unusable!"
- @echo ""
- @echo "If you are in any doubt, just do 'make all' (or just"
- @echo "'make'). It is likely that this is the SAFEST thing to do...."
- @exit 1
-
-install:
- @for i in $(DIRS) ; do \
- $(MAKE) -C $$i install ; \
- if [ $$? -ne 0 ]; then break ; fi ; \
- done
- install ./doc/man/*.3 $(PREFIX)/man/man3/
- install ./doc/man/*.8 $(PREFIX)/man/man8/
-
-sterile: .freezemake
- @$(MAKE) remove
- @$(MAKE) extraclean
-
-remove: .freezemake
- @for i in $(DIRS) ; do \
- $(MAKE) -C $$i remove ; \
- done
+prep:
+ rm -f security
+ ln -sf . security
clean:
- @rm -f *~ core
- @for i in $(DIRS) ; do \
- $(MAKE) -C $$i clean ; \
- done
-
-extraclean:
- @for i in $(DIRS) doc; do \
- $(MAKE) -C $$i extraclean ; \
- done
-
-check:
- @$(MAKE) -C conf check
+ if [ ! -f Make.Rules ]; then touch Make.Rules ; fi
+ for i in $(THINGSTOMAKE) ; do $(MAKE) -C $$i clean ; done
+ rm -f security *~ *.orig *.rej Make.Rules #*#
+
+distclean: clean
+ rm -f Make.Rules _pam_aconf.h
+ rm -f config.status config.cache config.log core
+
+maintainer-clean: distclean
+ @echo files should be ok for packaging now.
+
+# NB _pam_aconf.h.in changes will remake this too
+Make.Rules: configure Make.Rules.in _pam_aconf.h.in
+ @echo XXX - not sure how to preserve past configure options..
+ @echo XXX - so not attempting to. Feel free to run ./configure
+ @echo XXX - by hand, with the options you want.
+ ./configure
+
+_pam_aconf.h: Make.Rules
+
+configure: configure.in
+ @echo
+ @echo You do not appear to have an up-to-date ./configure file.
+ @echo Please run autoconf, and then ./configure [..options..]
+ @echo
+ @rm -f configure
+ @exit 1
-RCScheck:
- @$(MAKE) -C conf RCScheck
+$(THINGSTOMAKE): _pam_aconf.h prep
+ $(MAKE) -C $@ all
-# this can be used to see what hasn't been check'd into RCS
+install: _pam_aconf.h prep
+ $(MKDIR) $(FAKEROOT)$(INCLUDED)
+ $(INSTALL) -m 444 security/_pam_aconf.h $(FAKEROOT)$(INCLUDED)
+ for x in $(THINGSTOMAKE) ; do make -C $$x install ; done
-open:
- @find . \( -type f -a -perm 644 \) -print
+remove:
+ rm -f $(FAKEROOT)$(INCLUDED)/_pam_aconf.h
+ for x in $(THINGSTOMAKE) ; do make -C $$x remove ; done
release:
- @egrep '^DEBUG\_REL\=yes' Makefile|grep -v grep > /dev/null ;\
- if [ $$? -eq 0 ]; then \
- echo "You should first set DEBUG_REL to no" ; exit 1 ; fi
- $(MAKE) extraclean
- rm -f .freezemake
- touch .filelist .RCSlist
- chmod 600 .filelist .RCSlist
- cd .. ; find $(RELNAME) \! -type d -print | fgrep -v RCS | fgrep -v 'conf/.md5sum' > $(RELNAME)/.filelist
- cd .. ; find $(RELNAME) -type f -print | fgrep RCS | fgrep -v 'conf/.RCSsum' > $(RELNAME)/.RCSlist
- chmod 400 .filelist .RCSlist
- $(MAKE) check
- $(MAKE) RCScheck
- (cat .filelist ; echo $(RELNAME)/conf/.md5sum) | (cd .. ; tar -cz -f$(DISTFILE) -T-)
- (cat .RCSlist ; echo $(RELNAME)/conf/.RCSsum) | (cd .. ; tar -cz -fRCS+$(DISTFILE) -T-)
+ @if [ ! -f Make.Rules ]; then echo make Make.Rules first ; exit 1; fi
+ @if [ ! -L ../$(DISTNAME)-$(MAJOR_REL).$(MINOR_REL) ]; then \
+ echo generating ../$(DISTNAME)-$(MAJOR_REL).$(MINOR_REL) link ; \
+ ln -sf $(DISTNAME) ../$(DISTNAME)-$(MAJOR_REL).$(MINOR_REL) ; \
+ echo to ../$(DISTNAME) . ; fi
+ @diff ../$(DISTNAME)-$(MAJOR_REL).$(MINOR_REL)/Make.Rules Make.Rules
+ make distclean
+ cd .. ; tar zvfc $(DISTNAME)-$(MAJOR_REL).$(MINOR_REL).tar.gz \
+ --exclude CVS --exclude .cvsignore --exclude '.#*' \
+ $(DISTNAME)-$(MAJOR_REL).$(MINOR_REL)/*
+
diff --git a/contrib/libpam/README b/contrib/libpam/README
index 78a428ef46d3..1e769a5dba49 100644
--- a/contrib/libpam/README
+++ b/contrib/libpam/README
@@ -1,167 +1,28 @@
#
-# $Id: README,v 1.14 1997/04/05 07:04:46 morgan Exp $
+# $Id: README,v 1.3 2000/11/20 00:01:49 agmorgan Exp $
#
Hello!
-Thanks for downloading Linux-PAM-0.65.
-
---------------------------------------------------------------------
-Before you begin:
-
- * This distribution requires GNU's Make
- * It requires GNU's C-compiler: gcc (and 'ld')
- * it also requires the GNU shell: bash
- * some of the modules require the presence of libpwdb see redhat
- * two modules have some need for libcrack too..
-
---------------------------------------------------------------------
-[
-Zeroth (optional) thing to do: check the detatched "pgp" signature for
-this distribution file, it should be signed by
-
-Type Bits/KeyID Date User ID
-pub 1024/2A398175 1996/11/17 Andrew G. Morgan <morgan@linux.kernel.org>
-]
-
-First thing to do (I assume you have successfully unpacked it!) is to
-run:
-
- make check [ requires md5sum to be present ]
-
-This will also check that the distribution has arrived intact. [
-Later, If you change some things, running this command from this
-directory will show you what files you have altered. ]
-
-If you choose to get and install the RCS files that accompany this
-release, you may also run
-
- make RCScheck
-
-from this directory.
-
-Next, you should check the symbolic link
-
- .../Linux-PAM-X.YY/default.defs
-
-points to the file that best describes your system. The various *.defs
-files that are included in this distribution are to be found in the
-directory:
-
- .../Linux-PAM-X.YY/defs/
-
-This should configure the distribution to compile on your system. The
-default is the version I use for maintaining the distribution. [If you
-don't find one that suits your needs, please try to create one, email
-it to me and I will include it in a future release.]
-
-If you are running an ELF based Linux system you should be able to
-compile the distribution straight from the box. If you are running an
-a.out based system, then some of the functionality of Linux-PAM will
-be unavailable to you. Instead, you must switch the DYNAMIC variables
-*off* in your "defs" file: comment out the DYNAMIC and DYNAMIC_LIBPAM
-defines and uncomment the STATIC and STATIC_LIBPAM defines. NOTE, for
-ELF based systems, almost any combination of these four definitions is
-legal... If you have ELF, I recommend the default however.
-
-Second, try to compile it. Use the following command in *this*
-directory:
-
- make
-
-[ or 'make all' if you prefer ]. The first time you type make, it is
-likely to complain. This is to remind you to remove any libraries from
-previous versions of the distribution that are likely to confuse this
-make... Type 'make' again.
-
-Before you do the third thing. You should think about whether you want
-the default configuration scripts to be installed or not. If you have
-a working PAM based system you probably do *not* want this.. Whatever,
-before Linux-PAM installs the default scripts you will be prompted as
-to whether it is a good idea. Be sure to say NO if you are worried!
-** You have been warned. **
-
-Third, to install the stuff you need to be root. Do the following:
-
- su -c "make install"
-
-If everything has worked as intended there should now be
-
- some executables in ./bin/
- some filters for pam_filter in /usr/sbin/pam_filter/
- some configuration files:
- /etc/pam.conf
- /etc/security/*.conf
- libpam_misc.a (static library) in /usr/lib/
-
-In addition:
-
- if dynamically linked:
-
- libpam.so.XXX (shared library) in /usr/lib/
- libpam_misc.so.XXX (shared library) in /usr/lib/
- pam_*.so (modules) in /usr/lib/security/
-
- if statically linked:
-
- libpam.a (static library) in /usr/lib/
-
-[These are the default directories that I use. Your own system may
-differ as specified in your XXX.defs file.]
+Thanks for downloading Linux-PAM.
NOTES:
-* The documentation, what there is of it, is in ./doc. I am only
-including the sgml format source-files. But try to make .ps files
-available from the above http address. To locally use these sgml files
-you should have linuxdoc-sgml installed. Sorry, but I'm conserving net
-bandwidth by only including sources!
+How to use it is as follows:
-* The source for each module is to be found in ./modules/XXX. If you
-want to add a new one, make a directory like XXX for it. Add the name
-(XXX) to MODDIRS in ./modules/Makefile and hopefully it will become
-part of the overall make. Note, the Makefile in ./modules/ is now
-smart enough to check if the directory is there before it changes into
-it; If you want to start working on a module, send me its name and I
-will add it to the "official" Makefile.. This way, you should be able
-to insert your developing module into any new release, and not have to
-worry at first about letting it out to the public. This may also give
-other people some idea about whether a module is currently being
-worked on or not.
+ ./configure --help | less
+ ./configure <your-options>
+ make
-* Currently, you have to 'make' binaries from this directory. 'make
-clean', however, works in any directory that has a Makefile.
+Note, if you are worried - don't even think about doing the next line
+(most Linux distributions already support PAM out of the box, so if
+something goes wrong with installing the code from this version your
+box may stop working..)
-* Also, you can 'make remove' (as root) from *this* directory and it
-will delete the various installed files dotted around the system. THIS
-IS A VERY BAD IDEA IF YOUR SYSTEM DEPENDS ON PAM TO WORK!!!
+ make install
-* 'make sterile' does 'make remove' and then 'make extraclean', this
-might be required if you are alternating your choice of
-STATIC(_LIBPAM) and DYNAMIC(_LIBPAM) compilation. SEE COMMENT IN
-UPPERCASE IN PARAGRAPH ABOVE!!!!
-
-Best wishes
+That said, please report problems to me.
Andrew Morgan
-
-Email bugs/comments to: the Linux-PAM list <pam-list@redhat.com>
-or me <morgan@linux.kernel.org>
-
-To see about joining the mailing list, send the following email:
---------------------------------
-To: pam-list-request@redhat.com
-Subject: help
-<empty text>
---------------------------------
-
-Additionally, some Linux-PAM files have been known to be found at one
-or more of the following places (they are not always the most up to
-date...):
-
-http://www.redhat.com/linux-info/pam/
-
-ftp://bach.cis.temple.edu/pub/People/Alex/private/PAM
-ftp://ftp.redhat.com/pub/misc/
-ftp://linux.nrao.edu/pub/linux/ALPHA/PAM/
-ftp://tsx-11.mit.edu/pub/linux/ALPHA/PAM/
+<morgan@kernel.org>
+<agmorgan@users.sourceforge.net>
diff --git a/contrib/libpam/_pam_aconf.h.in b/contrib/libpam/_pam_aconf.h.in
new file mode 100644
index 000000000000..0da92b79e43a
--- /dev/null
+++ b/contrib/libpam/_pam_aconf.h.in
@@ -0,0 +1,64 @@
+/*
+ * $Id: _pam_aconf.h.in,v 1.4 2000/12/04 20:56:10 baggins Exp $
+ *
+ *
+ */
+
+#ifndef PAM_ACONF_H
+#define PAM_ACONF_H
+
+/* lots of stuff gets written to /tmp/pam-debug.log */
+#undef DEBUG
+
+/* build libraries with different names (suffixed with 'd') */
+#undef WITH_LIBDEBUG
+
+/* provide a global locking facility within libpam */
+#undef PAM_LOCKING
+
+/* GNU systems as a class, all have the feature.h file */
+#undef HAVE_FEATURES_H
+#ifdef HAVE_FEATURES_H
+# define _SVID_SOURCE
+# define _BSD_SOURCE
+# define __USE_BSD
+# define __USE_SVID
+# define __USE_MISC
+# define _GNU_SOURCE
+# include <features.h>
+#endif /* HAVE_FEATURES_H */
+
+/* we have libcrack available */
+#undef HAVE_LIBCRACK
+
+/* we have libcrypt - its not part of libc (do we need both definitions?) */
+#undef HAVE_LIBCRYPT
+#undef HAVE_CRYPT_H
+
+/* we have libndbm and/or libdb */
+#undef HAVE_DB_H
+#undef HAVE_NDBM_H
+
+/* have libfl (Flex) */
+#undef HAVE_LIBFL
+
+/* have libnsl - instead of libc support */
+#undef HAVE_LIBNSL
+
+/* have libpwdb - don't expect this to be important for much longer */
+#undef HAVE_LIBPWDB
+
+/* ugly hack to partially support old pam_strerror syntax */
+#undef UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT
+
+/* read both confs - read /etc/pam.d and /etc/pam.conf in serial */
+#undef PAM_READ_BOTH_CONFS
+
+#undef HAVE_PATHS_H
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+/* location of the mail spool directory */
+#undef PAM_PATH_MAILDIR
+
+#endif /* PAM_ACONF_H */
diff --git a/contrib/libpam/bin/README b/contrib/libpam/bin/README
index 92ab5253faa9..2d2fba52e4e4 100644
--- a/contrib/libpam/bin/README
+++ b/contrib/libpam/bin/README
@@ -1,14 +1,5 @@
##
-# $Id: README,v 1.6 1997/02/15 19:21:08 morgan Exp $
-##
-# $Log: README,v $
-# Revision 1.6 1997/02/15 19:21:08 morgan
-# fixed email
-#
-# Revision 1.5 1996/08/09 05:29:43 morgan
-# trimmed in line with the removal of applications from the distribution
-#
-#
+# $Id: README,v 1.2 2000/12/04 19:02:33 baggins Exp $
##
(now we are getting networked apps, be careful to try and test on a
diff --git a/contrib/libpam/conf/Makefile b/contrib/libpam/conf/Makefile
index 4fb9f7c40c60..67523c59f182 100644
--- a/contrib/libpam/conf/Makefile
+++ b/contrib/libpam/conf/Makefile
@@ -1,28 +1,5 @@
#
-# $Id: Makefile,v 1.8 1997/04/05 06:59:33 morgan Exp $
-#
-# $Log: Makefile,v $
-# Revision 1.8 1997/04/05 06:59:33 morgan
-# fakeroot and $(MAKE)
-#
-# Revision 1.7 1997/02/15 15:53:51 morgan
-# added lines to make pam_conv1
-#
-# Revision 1.6 1996/11/10 19:48:09 morgan
-# fix for systems that have not installed bash in /bin/
-#
-# Revision 1.5 1996/03/16 22:21:26 morgan
-# added 'make remove' option
-#
-# Revision 1.4 1996/03/10 21:01:47 morgan
-# added .ignore_age flag file
-#
-# Revision 1.3 1996/03/10 17:41:28 morgan
-# make RCScheck check for the presence of the executable before running
-# it!
-#
-# Revision 1.2 1996/03/10 17:16:42 morgan
-# added md5RCS/ RCScheck entry
+# $Id: Makefile,v 1.1.1.1 2000/06/20 22:10:44 agmorgan Exp $
#
#
@@ -47,9 +24,6 @@ remove:
check:
bash -f ./md5itall
-RCScheck:
- if [ -x ./md5RCS ]; then bash -f ./md5RCS ; fi
-
lclean:
rm -f core *~ .ignore_age
diff --git a/contrib/libpam/conf/md5itall b/contrib/libpam/conf/md5itall
index 6328a4f6fc5a..0f2656fe746b 100755
--- a/contrib/libpam/conf/md5itall
+++ b/contrib/libpam/conf/md5itall
@@ -1,8 +1,6 @@
#!/bin/bash
#
-# $Id$
-#
-# $Log$
+# $Id: md5itall,v 1.2 2000/12/04 19:02:33 baggins Exp $
#
# Created by Andrew G. Morgan (morgan@parc.power.net)
#
diff --git a/contrib/libpam/conf/pam.conf b/contrib/libpam/conf/pam.conf
index 2e4f0342189a..8e78e547a01b 100644
--- a/contrib/libpam/conf/pam.conf
+++ b/contrib/libpam/conf/pam.conf
@@ -1,9 +1,9 @@
# ---------------------------------------------------------------------------#
# /etc/pam.conf #
# #
-# Last modified by Andrew G. Morgan <morgan@parc.power.net> #
+# Last modified by Andrew G. Morgan <morgan@kernel.org> #
# ---------------------------------------------------------------------------#
-# $Id: pam.conf,v 1.18 1997/02/15 20:20:20 morgan Exp morgan $
+# $Id: pam.conf,v 1.2 2001/04/08 06:02:33 agmorgan Exp $
# ---------------------------------------------------------------------------#
# serv. module ctrl module [path] ...[args..] #
# name type flag #
@@ -11,46 +11,46 @@
#
# The PAM configuration file for the `chfn' service
#
-chfn auth required pam_pwdb.so
-chfn account required pam_pwdb.so
+chfn auth required pam_unix.so
+chfn account required pam_unix.so
chfn password required pam_cracklib.so retry=3
-chfn password required pam_pwdb.so shadow md5 use_authtok
+chfn password required pam_unix.so shadow md5 use_authtok
#
# The PAM configuration file for the `chsh' service
#
-chsh auth required pam_pwdb.so
-chsh account required pam_pwdb.so
+chsh auth required pam_unix.so
+chsh account required pam_unix.so
chsh password required pam_cracklib.so retry=3
-chsh password required pam_pwdb.so shadow md5 use_authtok
+chsh password required pam_unix.so shadow md5 use_authtok
#
# The PAM configuration file for the `ftp' service
#
ftp auth requisite pam_listfile.so \
item=user sense=deny file=/etc/ftpusers onerr=succeed
ftp auth requisite pam_shells.so
-ftp auth required pam_pwdb.so
-ftp account required pam_pwdb.so
+ftp auth required pam_unix.so
+ftp account required pam_unix.so
#
# The PAM configuration file for the `imap' service
#
-imap auth required pam_pwdb.so
-imap account required pam_pwdb.so
+imap auth required pam_unix.so
+imap account required pam_unix.so
#
# The PAM configuration file for the `login' service
#
login auth requisite pam_securetty.so
-login auth required pam_pwdb.so
+login auth required pam_unix.so
login auth optional pam_group.so
login account requisite pam_time.so
-login account required pam_pwdb.so
+login account required pam_unix.so
login password required pam_cracklib.so retry=3
-login password required pam_pwdb.so shadow md5 use_authtok
-login session required pam_pwdb.so
+login password required pam_unix.so shadow md5 use_authtok
+login session required pam_unix.so
#
# The PAM configuration file for the `netatalk' service
#
-netatalk auth required pam_pwdb.so
-netatalk account required pam_pwdb.so
+netatalk auth required pam_unix.so
+netatalk account required pam_unix.so
#
# The PAM configuration file for the `other' service
#
@@ -64,16 +64,16 @@ other session required pam_deny.so
# The PAM configuration file for the `passwd' service
#
passwd password requisite pam_cracklib.so retry=3
-passwd password required pam_pwdb.so shadow md5 use_authtok
+passwd password required pam_unix.so shadow md5 use_authtok
#
# The PAM configuration file for the `rexec' service
#
rexec auth requisite pam_securetty.so
rexec auth requisite pam_nologin.so
rexec auth sufficient pam_rhosts_auth.so
-rexec auth required pam_pwdb.so
-rexec account required pam_pwdb.so
-rexec session required pam_pwdb.so
+rexec auth required pam_unix.so
+rexec account required pam_unix.so
+rexec session required pam_unix.so
rexec session required pam_limits.so
#
# The PAM configuration file for the `rlogin' service
@@ -82,10 +82,10 @@ rexec session required pam_limits.so
rlogin auth requisite pam_securetty.so
rlogin auth requisite pam_nologin.so
rlogin auth required pam_rhosts_auth.so
-rlogin account required pam_pwdb.so
+rlogin account required pam_unix.so
rlogin password required pam_cracklib.so retry=3
-rlogin password required pam_pwdb.so shadow md5 use_authtok
-rlogin session required pam_pwdb.so
+rlogin password required pam_unix.so shadow md5 use_authtok
+rlogin session required pam_unix.so
rlogin session required pam_limits.so
#
# The PAM configuration file for the `rsh' service
@@ -93,34 +93,34 @@ rlogin session required pam_limits.so
rsh auth requisite pam_securetty.so
rsh auth requisite pam_nologin.so
rsh auth sufficient pam_rhosts_auth.so
-rsh auth required pam_pwdb.so
-rsh account required pam_pwdb.so
-rsh session required pam_pwdb.so
+rsh auth required pam_unix.so
+rsh account required pam_unix.so
+rsh session required pam_unix.so
rsh session required pam_limits.so
#
# The PAM configuration file for the `samba' service
#
-samba auth required pam_pwdb.so
-samba account required pam_pwdb.so
+samba auth required pam_unix.so
+samba account required pam_unix.so
#
# The PAM configuration file for the `su' service
#
su auth required pam_wheel.so
su auth sufficient pam_rootok.so
-su auth required pam_pwdb.so
-su account required pam_pwdb.so
-su session required pam_pwdb.so
+su auth required pam_unix.so
+su account required pam_unix.so
+su session required pam_unix.so
#
# The PAM configuration file for the `vlock' service
#
-vlock auth required pam_pwdb.so
+vlock auth required pam_unix.so
#
# The PAM configuration file for the `xdm' service
#
-xdm auth required pam_pwdb.so
-xdm account required pam_pwdb.so
+xdm auth required pam_unix.so
+xdm account required pam_unix.so
#
# The PAM configuration file for the `xlock' service
#
-xlock auth required pam_pwdb.so
+xlock auth required pam_unix.so
diff --git a/contrib/libpam/conf/pam_conv1/README b/contrib/libpam/conf/pam_conv1/README
index d3344bb34ff0..7a09df389c00 100644
--- a/contrib/libpam/conf/pam_conv1/README
+++ b/contrib/libpam/conf/pam_conv1/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.1 1997/02/15 15:50:50 morgan Exp $
+$Id: README,v 1.1.1.1 2000/06/20 22:10:45 agmorgan Exp $
This directory contains a untility to convert pam.conf files to a pam.d/
tree. The conversion program takes pam.conf from the standard input and
diff --git a/contrib/libpam/conf/pam_conv1/pam_conv.lex b/contrib/libpam/conf/pam_conv1/pam_conv.lex
index d5f618ef4518..ef8cb41a6cbf 100644
--- a/contrib/libpam/conf/pam_conv1/pam_conv.lex
+++ b/contrib/libpam/conf/pam_conv1/pam_conv.lex
@@ -1,7 +1,7 @@
%{
/*
- * $Id: pam_conv.lex,v 1.1 1997/01/23 05:35:50 morgan Exp $
+ * $Id: pam_conv.lex,v 1.1.1.1 2000/06/20 22:10:45 agmorgan Exp $
*
* Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
*
@@ -10,7 +10,7 @@
*/
const static char lexid[]=
- "$Id: pam_conv.lex,v 1.1 1997/01/23 05:35:50 morgan Exp $\n"
+ "$Id: pam_conv.lex,v 1.1.1.1 2000/06/20 22:10:45 agmorgan Exp $\n"
"Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>\n";
extern int current_line;
diff --git a/contrib/libpam/conf/pam_conv1/pam_conv.y b/contrib/libpam/conf/pam_conv1/pam_conv.y
index 8ce5ab08f023..a3307b847054 100644
--- a/contrib/libpam/conf/pam_conv1/pam_conv.y
+++ b/contrib/libpam/conf/pam_conv1/pam_conv.y
@@ -1,7 +1,7 @@
%{
/*
- * $Id: pam_conv.y,v 1.3 1997/02/15 15:50:50 morgan Exp morgan $
+ * $Id: pam_conv.y,v 1.1.1.1 2000/06/20 22:10:45 agmorgan Exp $
*
* Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
*
@@ -10,7 +10,7 @@
*/
const static char bisonid[]=
- "$Id: pam_conv.y,v 1.3 1997/02/15 15:50:50 morgan Exp morgan $\n"
+ "$Id: pam_conv.y,v 1.1.1.1 2000/06/20 22:10:45 agmorgan Exp $\n"
"Copyright (c) Andrew G. Morgan 1997-8 <morgan@linux.kernel.org>\n";
#include <string.h>
diff --git a/contrib/libpam/configure b/contrib/libpam/configure
new file mode 100755
index 000000000000..d63a2fba5760
--- /dev/null
+++ b/contrib/libpam/configure
@@ -0,0 +1,3548 @@
+#! /bin/sh
+
+# Guess values for system-dependent variables and create Makefiles.
+# Generated automatically using autoconf version 2.13
+# Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc.
+#
+# This configure script is free software; the Free Software Foundation
+# gives unlimited permission to copy, distribute and modify it.
+
+# Defaults:
+ac_help=
+ac_default_prefix=/usr/local
+# Any additions from configure.in:
+ac_default_prefix=
+ac_help="$ac_help
+ --enable-debug qspecify you are building with debugging on"
+ac_help="$ac_help
+ --enable-libdebug specify you are building debugging libraries"
+ac_help="$ac_help
+ --enable-fakeroot=<path to packaging directory>"
+ac_help="$ac_help
+ --enable-securedir=<path to location of PAMs> [default \$libdir/security]"
+ac_help="$ac_help
+ --enable-sconfigdir=<path to module conf files> [default \$sysconfdir/security]"
+ac_help="$ac_help
+ --enable-suplementedir=<path to module helper binaries> [default \$sbindir]"
+ac_help="$ac_help
+ --enable-includedir=<path to include location> - where to put <security>"
+ac_help="$ac_help
+ --enable-pamlocking configure libpam to observe a global authentication lock"
+ac_help="$ac_help
+ --enable-uglyhack configure libpam to try to honor old pam_strerror syntax"
+ac_help="$ac_help
+ --enable-read-both-confs read both /etc/pam.d and /etc/pam.conf files"
+ac_help="$ac_help
+ --enable-static-libpam build a libpam.a library"
+ac_help="$ac_help
+ --disable-dynamic-libpam do not build a shared libpam library"
+ac_help="$ac_help
+ --enable-static-modules do not make the modules dynamically loadable"
+ac_help="$ac_help
+ --disable-lckpwdf do not use the lckpwdf function"
+ac_help="$ac_help
+ --with-mailspool path to mail spool directory
+ [default _PATH_MAILDIR if defined in paths.h, otherwise /var/spool/mail]"
+
+# Initialize some variables set by options.
+# The variables have the same names as the options, with
+# dashes changed to underlines.
+build=NONE
+cache_file=./config.cache
+exec_prefix=NONE
+host=NONE
+no_create=
+nonopt=NONE
+no_recursion=
+prefix=NONE
+program_prefix=NONE
+program_suffix=NONE
+program_transform_name=s,x,x,
+silent=
+site=
+srcdir=
+target=NONE
+verbose=
+x_includes=NONE
+x_libraries=NONE
+bindir='${exec_prefix}/bin'
+sbindir='${exec_prefix}/sbin'
+libexecdir='${exec_prefix}/libexec'
+datadir='${prefix}/share'
+sysconfdir='${prefix}/etc'
+sharedstatedir='${prefix}/com'
+localstatedir='${prefix}/var'
+libdir='${exec_prefix}/lib'
+includedir='${prefix}/include'
+oldincludedir='/usr/include'
+infodir='${prefix}/info'
+mandir='${prefix}/man'
+
+# Initialize some other variables.
+subdirs=
+MFLAGS= MAKEFLAGS=
+SHELL=${CONFIG_SHELL-/bin/sh}
+# Maximum number of lines to put in a shell here document.
+ac_max_here_lines=12
+
+ac_prev=
+for ac_option
+do
+
+ # If the previous option needs an argument, assign it.
+ if test -n "$ac_prev"; then
+ eval "$ac_prev=\$ac_option"
+ ac_prev=
+ continue
+ fi
+
+ case "$ac_option" in
+ -*=*) ac_optarg=`echo "$ac_option" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) ac_optarg= ;;
+ esac
+
+ # Accept the important Cygnus configure options, so we can diagnose typos.
+
+ case "$ac_option" in
+
+ -bindir | --bindir | --bindi | --bind | --bin | --bi)
+ ac_prev=bindir ;;
+ -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*)
+ bindir="$ac_optarg" ;;
+
+ -build | --build | --buil | --bui | --bu)
+ ac_prev=build ;;
+ -build=* | --build=* | --buil=* | --bui=* | --bu=*)
+ build="$ac_optarg" ;;
+
+ -cache-file | --cache-file | --cache-fil | --cache-fi \
+ | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c)
+ ac_prev=cache_file ;;
+ -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \
+ | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*)
+ cache_file="$ac_optarg" ;;
+
+ -datadir | --datadir | --datadi | --datad | --data | --dat | --da)
+ ac_prev=datadir ;;
+ -datadir=* | --datadir=* | --datadi=* | --datad=* | --data=* | --dat=* \
+ | --da=*)
+ datadir="$ac_optarg" ;;
+
+ -disable-* | --disable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*disable-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ eval "enable_${ac_feature}=no" ;;
+
+ -enable-* | --enable-*)
+ ac_feature=`echo $ac_option|sed -e 's/-*enable-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_feature| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_feature: invalid feature name" 1>&2; exit 1; }
+ fi
+ ac_feature=`echo $ac_feature| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "enable_${ac_feature}='$ac_optarg'" ;;
+
+ -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \
+ | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \
+ | --exec | --exe | --ex)
+ ac_prev=exec_prefix ;;
+ -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \
+ | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \
+ | --exec=* | --exe=* | --ex=*)
+ exec_prefix="$ac_optarg" ;;
+
+ -gas | --gas | --ga | --g)
+ # Obsolete; use --with-gas.
+ with_gas=yes ;;
+
+ -help | --help | --hel | --he)
+ # Omit some internal or obsolete options to make the list less imposing.
+ # This message is too long to be a string in the A/UX 3.1 sh.
+ cat << EOF
+Usage: configure [options] [host]
+Options: [defaults in brackets after descriptions]
+Configuration:
+ --cache-file=FILE cache test results in FILE
+ --help print this message
+ --no-create do not create output files
+ --quiet, --silent do not print \`checking...' messages
+ --version print the version of autoconf that created configure
+Directory and file names:
+ --prefix=PREFIX install architecture-independent files in PREFIX
+ [$ac_default_prefix]
+ --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX
+ [same as prefix]
+ --bindir=DIR user executables in DIR [EPREFIX/bin]
+ --sbindir=DIR system admin executables in DIR [EPREFIX/sbin]
+ --libexecdir=DIR program executables in DIR [EPREFIX/libexec]
+ --datadir=DIR read-only architecture-independent data in DIR
+ [PREFIX/share]
+ --sysconfdir=DIR read-only single-machine data in DIR [PREFIX/etc]
+ --sharedstatedir=DIR modifiable architecture-independent data in DIR
+ [PREFIX/com]
+ --localstatedir=DIR modifiable single-machine data in DIR [PREFIX/var]
+ --libdir=DIR object code libraries in DIR [EPREFIX/lib]
+ --includedir=DIR C header files in DIR [PREFIX/include]
+ --oldincludedir=DIR C header files for non-gcc in DIR [/usr/include]
+ --infodir=DIR info documentation in DIR [PREFIX/info]
+ --mandir=DIR man documentation in DIR [PREFIX/man]
+ --srcdir=DIR find the sources in DIR [configure dir or ..]
+ --program-prefix=PREFIX prepend PREFIX to installed program names
+ --program-suffix=SUFFIX append SUFFIX to installed program names
+ --program-transform-name=PROGRAM
+ run sed PROGRAM on installed program names
+EOF
+ cat << EOF
+Host type:
+ --build=BUILD configure for building on BUILD [BUILD=HOST]
+ --host=HOST configure for HOST [guessed]
+ --target=TARGET configure for TARGET [TARGET=HOST]
+Features and packages:
+ --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
+ --enable-FEATURE[=ARG] include FEATURE [ARG=yes]
+ --with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
+ --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no)
+ --x-includes=DIR X include files are in DIR
+ --x-libraries=DIR X library files are in DIR
+EOF
+ if test -n "$ac_help"; then
+ echo "--enable and --with options recognized:$ac_help"
+ fi
+ exit 0 ;;
+
+ -host | --host | --hos | --ho)
+ ac_prev=host ;;
+ -host=* | --host=* | --hos=* | --ho=*)
+ host="$ac_optarg" ;;
+
+ -includedir | --includedir | --includedi | --included | --include \
+ | --includ | --inclu | --incl | --inc)
+ ac_prev=includedir ;;
+ -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \
+ | --includ=* | --inclu=* | --incl=* | --inc=*)
+ includedir="$ac_optarg" ;;
+
+ -infodir | --infodir | --infodi | --infod | --info | --inf)
+ ac_prev=infodir ;;
+ -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*)
+ infodir="$ac_optarg" ;;
+
+ -libdir | --libdir | --libdi | --libd)
+ ac_prev=libdir ;;
+ -libdir=* | --libdir=* | --libdi=* | --libd=*)
+ libdir="$ac_optarg" ;;
+
+ -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \
+ | --libexe | --libex | --libe)
+ ac_prev=libexecdir ;;
+ -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \
+ | --libexe=* | --libex=* | --libe=*)
+ libexecdir="$ac_optarg" ;;
+
+ -localstatedir | --localstatedir | --localstatedi | --localstated \
+ | --localstate | --localstat | --localsta | --localst \
+ | --locals | --local | --loca | --loc | --lo)
+ ac_prev=localstatedir ;;
+ -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \
+ | --localstate=* | --localstat=* | --localsta=* | --localst=* \
+ | --locals=* | --local=* | --loca=* | --loc=* | --lo=*)
+ localstatedir="$ac_optarg" ;;
+
+ -mandir | --mandir | --mandi | --mand | --man | --ma | --m)
+ ac_prev=mandir ;;
+ -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*)
+ mandir="$ac_optarg" ;;
+
+ -nfp | --nfp | --nf)
+ # Obsolete; use --without-fp.
+ with_fp=no ;;
+
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c)
+ no_create=yes ;;
+
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r)
+ no_recursion=yes ;;
+
+ -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \
+ | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \
+ | --oldin | --oldi | --old | --ol | --o)
+ ac_prev=oldincludedir ;;
+ -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \
+ | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \
+ | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*)
+ oldincludedir="$ac_optarg" ;;
+
+ -prefix | --prefix | --prefi | --pref | --pre | --pr | --p)
+ ac_prev=prefix ;;
+ -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*)
+ prefix="$ac_optarg" ;;
+
+ -program-prefix | --program-prefix | --program-prefi | --program-pref \
+ | --program-pre | --program-pr | --program-p)
+ ac_prev=program_prefix ;;
+ -program-prefix=* | --program-prefix=* | --program-prefi=* \
+ | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*)
+ program_prefix="$ac_optarg" ;;
+
+ -program-suffix | --program-suffix | --program-suffi | --program-suff \
+ | --program-suf | --program-su | --program-s)
+ ac_prev=program_suffix ;;
+ -program-suffix=* | --program-suffix=* | --program-suffi=* \
+ | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*)
+ program_suffix="$ac_optarg" ;;
+
+ -program-transform-name | --program-transform-name \
+ | --program-transform-nam | --program-transform-na \
+ | --program-transform-n | --program-transform- \
+ | --program-transform | --program-transfor \
+ | --program-transfo | --program-transf \
+ | --program-trans | --program-tran \
+ | --progr-tra | --program-tr | --program-t)
+ ac_prev=program_transform_name ;;
+ -program-transform-name=* | --program-transform-name=* \
+ | --program-transform-nam=* | --program-transform-na=* \
+ | --program-transform-n=* | --program-transform-=* \
+ | --program-transform=* | --program-transfor=* \
+ | --program-transfo=* | --program-transf=* \
+ | --program-trans=* | --program-tran=* \
+ | --progr-tra=* | --program-tr=* | --program-t=*)
+ program_transform_name="$ac_optarg" ;;
+
+ -q | -quiet | --quiet | --quie | --qui | --qu | --q \
+ | -silent | --silent | --silen | --sile | --sil)
+ silent=yes ;;
+
+ -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb)
+ ac_prev=sbindir ;;
+ -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \
+ | --sbi=* | --sb=*)
+ sbindir="$ac_optarg" ;;
+
+ -sharedstatedir | --sharedstatedir | --sharedstatedi \
+ | --sharedstated | --sharedstate | --sharedstat | --sharedsta \
+ | --sharedst | --shareds | --shared | --share | --shar \
+ | --sha | --sh)
+ ac_prev=sharedstatedir ;;
+ -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \
+ | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \
+ | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \
+ | --sha=* | --sh=*)
+ sharedstatedir="$ac_optarg" ;;
+
+ -site | --site | --sit)
+ ac_prev=site ;;
+ -site=* | --site=* | --sit=*)
+ site="$ac_optarg" ;;
+
+ -srcdir | --srcdir | --srcdi | --srcd | --src | --sr)
+ ac_prev=srcdir ;;
+ -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*)
+ srcdir="$ac_optarg" ;;
+
+ -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \
+ | --syscon | --sysco | --sysc | --sys | --sy)
+ ac_prev=sysconfdir ;;
+ -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \
+ | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*)
+ sysconfdir="$ac_optarg" ;;
+
+ -target | --target | --targe | --targ | --tar | --ta | --t)
+ ac_prev=target ;;
+ -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*)
+ target="$ac_optarg" ;;
+
+ -v | -verbose | --verbose | --verbos | --verbo | --verb)
+ verbose=yes ;;
+
+ -version | --version | --versio | --versi | --vers)
+ echo "configure generated by autoconf version 2.13"
+ exit 0 ;;
+
+ -with-* | --with-*)
+ ac_package=`echo $ac_option|sed -e 's/-*with-//' -e 's/=.*//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-_a-zA-Z0-9]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ case "$ac_option" in
+ *=*) ;;
+ *) ac_optarg=yes ;;
+ esac
+ eval "with_${ac_package}='$ac_optarg'" ;;
+
+ -without-* | --without-*)
+ ac_package=`echo $ac_option|sed -e 's/-*without-//'`
+ # Reject names that are not valid shell variable names.
+ if test -n "`echo $ac_package| sed 's/[-a-zA-Z0-9_]//g'`"; then
+ { echo "configure: error: $ac_package: invalid package name" 1>&2; exit 1; }
+ fi
+ ac_package=`echo $ac_package| sed 's/-/_/g'`
+ eval "with_${ac_package}=no" ;;
+
+ --x)
+ # Obsolete; use --with-x.
+ with_x=yes ;;
+
+ -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \
+ | --x-incl | --x-inc | --x-in | --x-i)
+ ac_prev=x_includes ;;
+ -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \
+ | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*)
+ x_includes="$ac_optarg" ;;
+
+ -x-libraries | --x-libraries | --x-librarie | --x-librari \
+ | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l)
+ ac_prev=x_libraries ;;
+ -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \
+ | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*)
+ x_libraries="$ac_optarg" ;;
+
+ -*) { echo "configure: error: $ac_option: invalid option; use --help to show usage" 1>&2; exit 1; }
+ ;;
+
+ *)
+ if test -n "`echo $ac_option| sed 's/[-a-z0-9.]//g'`"; then
+ echo "configure: warning: $ac_option: invalid host type" 1>&2
+ fi
+ if test "x$nonopt" != xNONE; then
+ { echo "configure: error: can only configure for one host and one target at a time" 1>&2; exit 1; }
+ fi
+ nonopt="$ac_option"
+ ;;
+
+ esac
+done
+
+if test -n "$ac_prev"; then
+ { echo "configure: error: missing argument to --`echo $ac_prev | sed 's/_/-/g'`" 1>&2; exit 1; }
+fi
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+# File descriptor usage:
+# 0 standard input
+# 1 file creation
+# 2 errors and warnings
+# 3 some systems may open it to /dev/tty
+# 4 used on the Kubota Titan
+# 6 checking for... messages and results
+# 5 compiler messages saved in config.log
+if test "$silent" = yes; then
+ exec 6>/dev/null
+else
+ exec 6>&1
+fi
+exec 5>./config.log
+
+echo "\
+This file contains any messages produced by compilers while
+running configure, to aid debugging if configure makes a mistake.
+" 1>&5
+
+# Strip out --no-create and --no-recursion so they do not pile up.
+# Also quote any args containing shell metacharacters.
+ac_configure_args=
+for ac_arg
+do
+ case "$ac_arg" in
+ -no-create | --no-create | --no-creat | --no-crea | --no-cre \
+ | --no-cr | --no-c) ;;
+ -no-recursion | --no-recursion | --no-recursio | --no-recursi \
+ | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) ;;
+ *" "*|*" "*|*[\[\]\~\#\$\^\&\*\(\)\{\}\\\|\;\<\>\?]*)
+ ac_configure_args="$ac_configure_args '$ac_arg'" ;;
+ *) ac_configure_args="$ac_configure_args $ac_arg" ;;
+ esac
+done
+
+# NLS nuisances.
+# Only set these to C if already set. These must not be set unconditionally
+# because not all systems understand e.g. LANG=C (notably SCO).
+# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'!
+# Non-C LC_CTYPE values break the ctype check.
+if test "${LANG+set}" = set; then LANG=C; export LANG; fi
+if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi
+if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi
+if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi
+
+# confdefs.h avoids OS command line length limits that DEFS can exceed.
+rm -rf conftest* confdefs.h
+# AIX cpp loses on an empty file, so make sure it contains at least a newline.
+echo > confdefs.h
+
+# A filename unique to this package, relative to the directory that
+# configure is in, which we can look for to find out if srcdir is correct.
+ac_unique_file=conf/pam_conv1/pam_conv.y
+
+# Find the source files, if location was not specified.
+if test -z "$srcdir"; then
+ ac_srcdir_defaulted=yes
+ # Try the directory containing this script, then its parent.
+ ac_prog=$0
+ ac_confdir=`echo $ac_prog|sed 's%/[^/][^/]*$%%'`
+ test "x$ac_confdir" = "x$ac_prog" && ac_confdir=.
+ srcdir=$ac_confdir
+ if test ! -r $srcdir/$ac_unique_file; then
+ srcdir=..
+ fi
+else
+ ac_srcdir_defaulted=no
+fi
+if test ! -r $srcdir/$ac_unique_file; then
+ if test "$ac_srcdir_defaulted" = yes; then
+ { echo "configure: error: can not find sources in $ac_confdir or .." 1>&2; exit 1; }
+ else
+ { echo "configure: error: can not find sources in $srcdir" 1>&2; exit 1; }
+ fi
+fi
+srcdir=`echo "${srcdir}" | sed 's%\([^/]\)/*$%\1%'`
+
+# Prefer explicitly selected file to automatically selected ones.
+if test -z "$CONFIG_SITE"; then
+ if test "x$prefix" != xNONE; then
+ CONFIG_SITE="$prefix/share/config.site $prefix/etc/config.site"
+ else
+ CONFIG_SITE="$ac_default_prefix/share/config.site $ac_default_prefix/etc/config.site"
+ fi
+fi
+for ac_site_file in $CONFIG_SITE; do
+ if test -r "$ac_site_file"; then
+ echo "loading site script $ac_site_file"
+ . "$ac_site_file"
+ fi
+done
+
+if test -r "$cache_file"; then
+ echo "loading cache $cache_file"
+ . $cache_file
+else
+ echo "creating cache $cache_file"
+ > $cache_file
+fi
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+ac_exeext=
+ac_objext=o
+if (echo "testing\c"; echo 1,2,3) | grep c >/dev/null; then
+ # Stardent Vistra SVR4 grep lacks -e, says ghazi@caip.rutgers.edu.
+ if (echo -n testing; echo 1,2,3) | sed s/-n/xn/ | grep xn >/dev/null; then
+ ac_n= ac_c='
+' ac_t=' '
+ else
+ ac_n=-n ac_c= ac_t=
+ fi
+else
+ ac_n= ac_c='\c' ac_t=
+fi
+
+
+
+
+
+
+LIBPAM_VERSION_MAJOR=0
+LIBPAM_VERSION_MINOR=75
+
+
+
+cat >> confdefs.h <<\EOF
+#define LIBPAM_VERSION_MAJOR 1
+EOF
+
+cat >> confdefs.h <<\EOF
+#define LIBPAM_VERSION_MINOR 1
+EOF
+
+
+
+
+
+
+CC=gcc ;
+CONF_CFLAGS= ;
+MKDIR="mkdir -p" ;
+LOCALSRCDIR=`/bin/pwd` ;
+OS=`uname|sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+
+
+DYNTYPE=so ;
+USESONAME=yes ;
+NEEDSONAME=yes ;
+SHLIBMODE=755 ;
+
+INSTALL=/usr/bin/install ;
+
+# Extract the first word of "gcc", so it can be a program name with args.
+set dummy gcc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:596: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="gcc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$CC"; then
+ # Extract the first word of "cc", so it can be a program name with args.
+set dummy cc; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:626: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_prog_rejected=no
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ if test "$ac_dir/$ac_word" = "/usr/ucb/cc"; then
+ ac_prog_rejected=yes
+ continue
+ fi
+ ac_cv_prog_CC="cc"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+if test $ac_prog_rejected = yes; then
+ # We found a bogon in the path, so make sure we never use it.
+ set dummy $ac_cv_prog_CC
+ shift
+ if test $# -gt 0; then
+ # We chose a different compiler from the bogus one.
+ # However, it has the same basename, so the bogon will be chosen
+ # first if we set CC to just the basename; use the full file name.
+ shift
+ set dummy "$ac_dir/$ac_word" "$@"
+ shift
+ ac_cv_prog_CC="$@"
+ fi
+fi
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test -z "$CC"; then
+ case "`uname -s`" in
+ *win32* | *WIN32*)
+ # Extract the first word of "cl", so it can be a program name with args.
+set dummy cl; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:677: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$CC"; then
+ ac_cv_prog_CC="$CC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_CC="cl"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+CC="$ac_cv_prog_CC"
+if test -n "$CC"; then
+ echo "$ac_t""$CC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+ ;;
+ esac
+ fi
+ test -z "$CC" && { echo "configure: error: no acceptable cc found in \$PATH" 1>&2; exit 1; }
+fi
+
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6
+echo "configure:709: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5
+
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+cat > conftest.$ac_ext << EOF
+
+#line 720 "configure"
+#include "confdefs.h"
+
+main(){return(0);}
+EOF
+if { (eval echo configure:725: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ ac_cv_prog_cc_works=yes
+ # If we can't run a trivial program, we are probably using a cross compiler.
+ if (./conftest; exit) 2>/dev/null; then
+ ac_cv_prog_cc_cross=no
+ else
+ ac_cv_prog_cc_cross=yes
+ fi
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ ac_cv_prog_cc_works=no
+fi
+rm -fr conftest*
+ac_ext=c
+# CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options.
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='${CC-cc} -c $CFLAGS $CPPFLAGS conftest.$ac_ext 1>&5'
+ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS 1>&5'
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo "$ac_t""$ac_cv_prog_cc_works" 1>&6
+if test $ac_cv_prog_cc_works = no; then
+ { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; }
+fi
+echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6
+echo "configure:751: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5
+echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6
+cross_compiling=$ac_cv_prog_cc_cross
+
+echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6
+echo "configure:756: checking whether we are using GNU C" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.c <<EOF
+#ifdef __GNUC__
+ yes;
+#endif
+EOF
+if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:765: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then
+ ac_cv_prog_gcc=yes
+else
+ ac_cv_prog_gcc=no
+fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc" 1>&6
+
+if test $ac_cv_prog_gcc = yes; then
+ GCC=yes
+else
+ GCC=
+fi
+
+ac_test_CFLAGS="${CFLAGS+set}"
+ac_save_CFLAGS="$CFLAGS"
+CFLAGS=
+echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6
+echo "configure:784: checking whether ${CC-cc} accepts -g" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ echo 'void f(){}' > conftest.c
+if test -z "`${CC-cc} -g -c conftest.c 2>&1`"; then
+ ac_cv_prog_cc_g=yes
+else
+ ac_cv_prog_cc_g=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_prog_cc_g" 1>&6
+if test "$ac_test_CFLAGS" = set; then
+ CFLAGS="$ac_save_CFLAGS"
+elif test $ac_cv_prog_cc_g = yes; then
+ if test "$GCC" = yes; then
+ CFLAGS="-g -O2"
+ else
+ CFLAGS="-g"
+ fi
+else
+ if test "$GCC" = yes; then
+ CFLAGS="-O2"
+ else
+ CFLAGS=
+ fi
+fi
+
+for ac_prog in 'bison -y' byacc
+do
+# Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:820: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$YACC"; then
+ ac_cv_prog_YACC="$YACC" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_YACC="$ac_prog"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+fi
+fi
+YACC="$ac_cv_prog_YACC"
+if test -n "$YACC"; then
+ echo "$ac_t""$YACC" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+test -n "$YACC" && break
+done
+test -n "$YACC" || YACC="yacc"
+
+# Extract the first word of "flex", so it can be a program name with args.
+set dummy flex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:853: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$LEX"; then
+ ac_cv_prog_LEX="$LEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_LEX="flex"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_LEX" && ac_cv_prog_LEX="lex"
+fi
+fi
+LEX="$ac_cv_prog_LEX"
+if test -n "$LEX"; then
+ echo "$ac_t""$LEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test -z "$LEXLIB"
+then
+ case "$LEX" in
+ flex*) ac_lib=fl ;;
+ *) ac_lib=l ;;
+ esac
+ echo $ac_n "checking for yywrap in -l$ac_lib""... $ac_c" 1>&6
+echo "configure:887: checking for yywrap in -l$ac_lib" >&5
+ac_lib_var=`echo $ac_lib'_'yywrap | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-l$ac_lib $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 895 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yywrap();
+
+int main() {
+yywrap()
+; return 0; }
+EOF
+if { (eval echo configure:906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LEXLIB="-l$ac_lib"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6
+echo "configure:929: checking whether ln -s works" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ rm -f conftestdata
+if ln -s X conftestdata 2>/dev/null
+then
+ rm -f conftestdata
+ ac_cv_prog_LN_S="ln -s"
+else
+ ac_cv_prog_LN_S=ln
+fi
+fi
+LN_S="$ac_cv_prog_LN_S"
+if test "$ac_cv_prog_LN_S" = "ln -s"; then
+ echo "$ac_t""yes" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6
+echo "configure:950: checking whether ${MAKE-make} sets \${MAKE}" >&5
+set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftestmake <<\EOF
+all:
+ @echo 'ac_maketemp="${MAKE}"'
+EOF
+# GNU make sometimes prints "make[1]: Entering...", which would confuse us.
+eval `${MAKE-make} -f conftestmake 2>/dev/null | grep temp=`
+if test -n "$ac_maketemp"; then
+ eval ac_cv_prog_make_${ac_make}_set=yes
+else
+ eval ac_cv_prog_make_${ac_make}_set=no
+fi
+rm -f conftestmake
+fi
+if eval "test \"`echo '$ac_cv_prog_make_'${ac_make}_set`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ SET_MAKE=
+else
+ echo "$ac_t""no" 1>&6
+ SET_MAKE="MAKE=${MAKE-make}"
+fi
+
+
+
+# Check whether --enable-debug or --disable-debug was given.
+if test "${enable_debug+set}" = set; then
+ enableval="$enable_debug"
+ WITH_DEBUG=yes ; cat >> confdefs.h <<\EOF
+#define DEBUG 1
+EOF
+
+else
+ WITH_DEBUG=no
+fi
+
+
+
+# Check whether --enable-libdebug or --disable-libdebug was given.
+if test "${enable_libdebug+set}" = set; then
+ enableval="$enable_libdebug"
+ WITH_LIBDEBUG=yes ; cat >> confdefs.h <<\EOF
+#define WITH_LIBDEBUG 1
+EOF
+
+else
+ WITH_LIBDEBUG=no
+fi
+
+
+
+# Check whether --enable-fakeroot or --disable-fakeroot was given.
+if test "${enable_fakeroot+set}" = set; then
+ enableval="$enable_fakeroot"
+ FAKEROOT=$enableval
+fi
+
+
+
+# Check whether --enable-securedir or --disable-securedir was given.
+if test "${enable_securedir+set}" = set; then
+ enableval="$enable_securedir"
+ SECUREDIR=$enableval
+else
+ SECUREDIR=$libdir/security
+fi
+
+
+
+# Check whether --enable-sconfigdir or --disable-sconfigdir was given.
+if test "${enable_sconfigdir+set}" = set; then
+ enableval="$enable_sconfigdir"
+ SCONFIGDIR=$enableval
+else
+ SCONFIGDIR=$sysconfdir/security
+fi
+
+
+
+# Check whether --enable-suplementedir or --disable-suplementedir was given.
+if test "${enable_suplementedir+set}" = set; then
+ enableval="$enable_suplementedir"
+ SUPLEMENTED=$enableval
+else
+ SUPLEMENTED=$sbindir
+fi
+
+
+
+# Check whether --enable-includedir or --disable-includedir was given.
+if test "${enable_includedir+set}" = set; then
+ enableval="$enable_includedir"
+ INCLUDEDIR=$enableval
+else
+ INCLUDEDIR=/usr/include
+fi
+
+
+
+# Check whether --enable-pamlocking or --disable-pamlocking was given.
+if test "${enable_pamlocking+set}" = set; then
+ enableval="$enable_pamlocking"
+ WITH_PAMLOCKING=yes ; cat >> confdefs.h <<\EOF
+#define PAM_LOCKING 1
+EOF
+
+else
+ WITH_PAMLOCKING=no
+fi
+
+
+
+# Check whether --enable-uglyhack or --disable-uglyhack was given.
+if test "${enable_uglyhack+set}" = set; then
+ enableval="$enable_uglyhack"
+ cat >> confdefs.h <<\EOF
+#define UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT 1
+EOF
+
+fi
+
+
+# Check whether --enable-read-both-confs or --disable-read-both-confs was given.
+if test "${enable_read_both_confs+set}" = set; then
+ enableval="$enable_read_both_confs"
+ cat >> confdefs.h <<\EOF
+#define PAM_READ_BOTH_CONFS 1
+EOF
+
+fi
+
+
+
+# Check whether --enable-static-libpam or --disable-static-libpam was given.
+if test "${enable_static_libpam+set}" = set; then
+ enableval="$enable_static_libpam"
+ STATIC_LIBPAM=yes
+else
+ STATIC_LIBPAM=no
+fi
+
+
+
+# Check whether --enable-dynamic-libpam or --disable-dynamic-libpam was given.
+if test "${enable_dynamic_libpam+set}" = set; then
+ enableval="$enable_dynamic_libpam"
+ DYNAMIC_LIBPAM=no
+else
+ DYNAMIC_LIBPAM=yes
+fi
+
+
+
+DYNAMIC=-DPAM_DYNAMIC
+
+
+# Check whether --enable-static-modules or --disable-static-modules was given.
+if test "${enable_static_modules+set}" = set; then
+ enableval="$enable_static_modules"
+ STATIC=-DPAM_STATIC
+fi
+
+
+
+# Check whether --enable-lckpwdf or --disable-lckpwdf was given.
+if test "${enable_lckpwdf+set}" = set; then
+ enableval="$enable_lckpwdf"
+ WITH_LCKPWDF=no
+else
+ WITH_LCKPWDF=yes
+fi
+
+
+
+echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6
+echo "configure:1128: checking how to run the C preprocessor" >&5
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+if eval "test \"`echo '$''{'ac_cv_prog_CPP'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ # This must be in double quotes, not single quotes, because CPP may get
+ # substituted into the Makefile and "${CC-cc}" will confuse make.
+ CPP="${CC-cc} -E"
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp.
+ cat > conftest.$ac_ext <<EOF
+#line 1143 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1149: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -E -traditional-cpp"
+ cat > conftest.$ac_ext <<EOF
+#line 1160 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1166: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP="${CC-cc} -nologo -E"
+ cat > conftest.$ac_ext <<EOF
+#line 1177 "configure"
+#include "confdefs.h"
+#include <assert.h>
+Syntax Error
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1183: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ :
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ CPP=/lib/cpp
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+fi
+rm -f conftest*
+ ac_cv_prog_CPP="$CPP"
+fi
+ CPP="$ac_cv_prog_CPP"
+else
+ ac_cv_prog_CPP="$CPP"
+fi
+echo "$ac_t""$CPP" 1>&6
+
+for ac_hdr in paths.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1211: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1216 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1221: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+# Check whether --with-mailspool or --without-mailspool was given.
+if test "${with_mailspool+set}" = set; then
+ withval="$with_mailspool"
+ with_mailspool=${withval}
+fi
+
+if test x$with_mailspool != x ; then
+ pam_mail_spool="\"$with_mailspool\""
+else
+ if test "$cross_compiling" = yes; then
+ pam_mail_spool="\"/var/spool/mail\""
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1260 "configure"
+#include "confdefs.h"
+
+#include <paths.h>
+int main() {
+#ifdef _PATH_MAILDIR
+exit(0);
+#else
+exit(1);
+#endif
+}
+EOF
+if { (eval echo configure:1272: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ pam_mail_spool="_PATH_MAILDIR"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ pam_mail_spool="\"/var/spool/mail\""
+fi
+rm -fr conftest*
+fi
+
+fi
+cat >> confdefs.h <<EOF
+#define PAM_PATH_MAILDIR $pam_mail_spool
+EOF
+
+
+echo $ac_n "checking for __libc_sched_setscheduler in -lc""... $ac_c" 1>&6
+echo "configure:1291: checking for __libc_sched_setscheduler in -lc" >&5
+ac_lib_var=`echo c'_'__libc_sched_setscheduler | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1299 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char __libc_sched_setscheduler();
+
+int main() {
+__libc_sched_setscheduler()
+; return 0; }
+EOF
+if { (eval echo configure:1310: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ PAM_NEEDS_LIBC=
+else
+ echo "$ac_t""no" 1>&6
+PAM_NEEDS_LIBC=-lc
+fi
+
+
+
+echo $ac_n "checking for lckpwdf in -lc""... $ac_c" 1>&6
+echo "configure:1334: checking for lckpwdf in -lc" >&5
+ac_lib_var=`echo c'_'lckpwdf | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lc $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1342 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char lckpwdf();
+
+int main() {
+lckpwdf()
+; return 0; }
+EOF
+if { (eval echo configure:1353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LCKPWDF=yes
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LCKPWDF=no
+fi
+
+
+
+echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6
+echo "configure:1377: checking for dlopen in -ldl" >&5
+ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1385 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dlopen();
+
+int main() {
+dlopen()
+; return 0; }
+EOF
+if { (eval echo configure:1396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBDL=-ldl
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+
+
+echo $ac_n "checking for FascistCheck in -lcrack""... $ac_c" 1>&6
+echo "configure:1419: checking for FascistCheck in -lcrack" >&5
+ac_lib_var=`echo crack'_'FascistCheck | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrack $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1427 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char FascistCheck();
+
+int main() {
+FascistCheck()
+; return 0; }
+EOF
+if { (eval echo configure:1438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBCRACK=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRACK 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBCRACK=no
+fi
+
+
+
+echo $ac_n "checking for fcrypt in -lcrypt""... $ac_c" 1>&6
+echo "configure:1465: checking for fcrypt in -lcrypt" >&5
+ac_lib_var=`echo crypt'_'fcrypt | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lcrypt $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1473 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char fcrypt();
+
+int main() {
+fcrypt()
+; return 0; }
+EOF
+if { (eval echo configure:1484: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBCRYPT=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBCRYPT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBCRYPT=no
+fi
+
+
+echo $ac_n "checking for logwtmp in -lutil""... $ac_c" 1>&6
+echo "configure:1510: checking for logwtmp in -lutil" >&5
+ac_lib_var=`echo util'_'logwtmp | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lutil $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1518 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char logwtmp();
+
+int main() {
+logwtmp()
+; return 0; }
+EOF
+if { (eval echo configure:1529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBUTIL=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBUTIL 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBUTIL=no
+fi
+
+
+echo $ac_n "checking for dbm_store in -lndbm""... $ac_c" 1>&6
+echo "configure:1555: checking for dbm_store in -lndbm" >&5
+ac_lib_var=`echo ndbm'_'dbm_store | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lndbm $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1563 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dbm_store();
+
+int main() {
+dbm_store()
+; return 0; }
+EOF
+if { (eval echo configure:1574: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBNDBM=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBNDBM 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBNDBM=no
+fi
+
+
+echo $ac_n "checking for dbm_store in -ldb""... $ac_c" 1>&6
+echo "configure:1600: checking for dbm_store in -ldb" >&5
+ac_lib_var=`echo db'_'dbm_store | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldb $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1608 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char dbm_store();
+
+int main() {
+dbm_store()
+; return 0; }
+EOF
+if { (eval echo configure:1619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBDB=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBDB 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBDB=no
+fi
+
+
+echo $ac_n "checking for yylex in -lfl""... $ac_c" 1>&6
+echo "configure:1645: checking for yylex in -lfl" >&5
+ac_lib_var=`echo fl'_'yylex | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lfl HAVE_LIBFL=no $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1653 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yylex();
+
+int main() {
+yylex()
+; return 0; }
+EOF
+if { (eval echo configure:1664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ yyterminate
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBFL=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBFL 1
+EOF
+
+fi
+
+
+echo $ac_n "checking for yp_maplist in -lnsl""... $ac_c" 1>&6
+echo "configure:1690: checking for yp_maplist in -lnsl" >&5
+ac_lib_var=`echo nsl'_'yp_maplist | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lnsl $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1698 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char yp_maplist();
+
+int main() {
+yp_maplist()
+; return 0; }
+EOF
+if { (eval echo configure:1709: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBNSL=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBNSL 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBNSL=no
+fi
+
+
+echo $ac_n "checking for pwdb_db_name in -lpwdb""... $ac_c" 1>&6
+echo "configure:1735: checking for pwdb_db_name in -lpwdb" >&5
+ac_lib_var=`echo pwdb'_'pwdb_db_name | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lpwdb $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1743 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char pwdb_db_name();
+
+int main() {
+pwdb_db_name()
+; return 0; }
+EOF
+if { (eval echo configure:1754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ HAVE_LIBPWDB=yes ; cat >> confdefs.h <<\EOF
+#define HAVE_LIBPWDB 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+HAVE_LIBPWDB=no
+fi
+
+
+
+ac_header_dirent=no
+for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
+echo "configure:1785: checking for $ac_hdr that defines DIR" >&5
+if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1790 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <$ac_hdr>
+int main() {
+DIR *dirp = 0;
+; return 0; }
+EOF
+if { (eval echo configure:1798: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_dirent_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_dirent_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+ ac_header_dirent=$ac_hdr; break
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
+if test $ac_header_dirent = dirent.h; then
+echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
+echo "configure:1823: checking for opendir in -ldir" >&5
+ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-ldir $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1831 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1842: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -ldir"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+else
+echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
+echo "configure:1864: checking for opendir in -lx" >&5
+ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
+if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_save_LIBS="$LIBS"
+LIBS="-lx $LIBS"
+cat > conftest.$ac_ext <<EOF
+#line 1872 "configure"
+#include "confdefs.h"
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char opendir();
+
+int main() {
+opendir()
+; return 0; }
+EOF
+if { (eval echo configure:1883: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_lib_$ac_lib_var=no"
+fi
+rm -f conftest*
+LIBS="$ac_save_LIBS"
+
+fi
+if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ LIBS="$LIBS -lx"
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6
+echo "configure:1906: checking for ANSI C header files" >&5
+if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1911 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1919: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ ac_cv_header_stdc=yes
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1936 "configure"
+#include "confdefs.h"
+#include <string.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "memchr" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+cat > conftest.$ac_ext <<EOF
+#line 1954 "configure"
+#include "confdefs.h"
+#include <stdlib.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "free" >/dev/null 2>&1; then
+ :
+else
+ rm -rf conftest*
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+if test "$cross_compiling" = yes; then
+ :
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1975 "configure"
+#include "confdefs.h"
+#include <ctype.h>
+#define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+#define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int main () { int i; for (i = 0; i < 256; i++)
+if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2);
+exit (0); }
+
+EOF
+if { (eval echo configure:1986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ :
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_header_stdc=no
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_header_stdc" 1>&6
+if test $ac_cv_header_stdc = yes; then
+ cat >> confdefs.h <<\EOF
+#define STDC_HEADERS 1
+EOF
+
+fi
+
+echo $ac_n "checking for sys/wait.h that is POSIX.1 compatible""... $ac_c" 1>&6
+echo "configure:2010: checking for sys/wait.h that is POSIX.1 compatible" >&5
+if eval "test \"`echo '$''{'ac_cv_header_sys_wait_h'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2015 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/wait.h>
+#ifndef WEXITSTATUS
+#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
+#endif
+#ifndef WIFEXITED
+#define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
+#endif
+int main() {
+int s;
+wait (&s);
+s = WIFEXITED (s) ? WEXITSTATUS (s) : 1;
+; return 0; }
+EOF
+if { (eval echo configure:2031: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_sys_wait_h=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_sys_wait_h" 1>&6
+if test $ac_cv_header_sys_wait_h = yes; then
+ cat >> confdefs.h <<\EOF
+#define HAVE_SYS_WAIT_H 1
+EOF
+
+fi
+
+for ac_hdr in fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h termio.h unistd.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2055: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2060 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2065: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_hdr in features.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2096: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2101 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2106: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_hdr in crypt.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2137: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2142 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2147: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+for ac_hdr in ndbm.h db.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2178: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2183 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2188: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+HAVE_NDBM_H=$ac_cv_header_ndbm_h
+
+
+for ac_hdr in lastlog.h utmp.h utmpx.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:2221: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2226 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:2231: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+
+echo $ac_n "checking path to cracklib dictionary""... $ac_c" 1>&6
+echo "configure:2260: checking path to cracklib dictionary" >&5
+DICT_DIR_CANDIDATES="/usr/lib /usr/share/dict /usr/share/lib \
+ /usr/local/lib /usr/local/share/lib"
+DICT_FILE_CANDIDATES="pw_dict cracklib_dict"
+CRACKLIB_DICTPATH=""
+for d in $DICT_DIR_CANDIDATES ; do
+ for f in $DICT_FILE_CANDIDATES ; do
+ if test -r $d/$f.hwm ; then
+ CRACKLIB_DICTPATH=$d/$f
+ break 2
+ elif test -r $d/dict/$f.hwm ; then
+ CRACKLIB_DICTPATH=$d/dict/$f
+ break 2
+ fi
+ done
+done
+if test -z "$CRACKLIB_DICTPATH" ; then
+ echo "$ac_t""none found" 1>&6
+else
+ echo "$ac_t""$CRACKLIB_DICTPATH" 1>&6
+fi
+
+
+
+GCC_WARNINGS="-Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow"
+
+if test "$GCC" = yes; then
+###
+### Non-Linux needs attention on per-OS basis
+ OS_CFLAGS="-ansi -D_POSIX_SOURCE -pedantic"
+ WARNINGS="$GCC_WARNINGS"
+ PIC="-fPIC"
+#can/should we use LD=gcc ???
+ LD=ld
+ LD_D="gcc -shared -Xlinker -x"
+ LD_L="$LD -x -shared"
+ RANLIB=ranlib
+ STRIP=strip
+ CC_STATIC="-Xlinker -export-dynamic"
+else
+###
+### Non-gcc needs attention on per-OS basis
+###
+### [These are Solaris-C specific...]
+ OS_CFLAGS=""
+ WARNINGS=""
+ PIC="-K pic"
+ LD=ld
+ LD_D="cc -z text -G -R."
+ LD_L="$LD_D"
+ RANLIB=ranlib
+ STRIP=strip
+ CC_STATIC=
+fi
+
+
+
+
+
+
+
+
+
+
+
+echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
+echo "configure:2329: checking whether byte ordering is bigendian" >&5
+if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_cv_c_bigendian=unknown
+# See if sys/param.h defines the BYTE_ORDER macro.
+cat > conftest.$ac_ext <<EOF
+#line 2336 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if !BYTE_ORDER || !BIG_ENDIAN || !LITTLE_ENDIAN
+ bogus endian macros
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2347: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ # It does; now see whether it defined to BIG_ENDIAN or not.
+cat > conftest.$ac_ext <<EOF
+#line 2351 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/param.h>
+int main() {
+
+#if BYTE_ORDER != BIG_ENDIAN
+ not big endian
+#endif
+; return 0; }
+EOF
+if { (eval echo configure:2362: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_bigendian=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_bigendian=no
+fi
+rm -f conftest*
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+fi
+rm -f conftest*
+if test $ac_cv_c_bigendian = unknown; then
+if test "$cross_compiling" = yes; then
+ { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2382 "configure"
+#include "confdefs.h"
+main () {
+ /* Are we little or big endian? From Harbison&Steele. */
+ union
+ {
+ long l;
+ char c[sizeof (long)];
+ } u;
+ u.l = 1;
+ exit (u.c[sizeof (long) - 1] == 1);
+}
+EOF
+if { (eval echo configure:2395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_c_bigendian=no
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_c_bigendian=yes
+fi
+rm -fr conftest*
+fi
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_c_bigendian" 1>&6
+if test $ac_cv_c_bigendian = yes; then
+ cat >> confdefs.h <<\EOF
+#define WORDS_BIGENDIAN 1
+EOF
+
+fi
+
+echo $ac_n "checking for working const""... $ac_c" 1>&6
+echo "configure:2419: checking for working const" >&5
+if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2424 "configure"
+#include "confdefs.h"
+
+int main() {
+
+/* Ultrix mips cc rejects this. */
+typedef int charset[2]; const charset x;
+/* SunOS 4.1.1 cc rejects this. */
+char const *const *ccp;
+char **p;
+/* NEC SVR4.0.2 mips cc rejects this. */
+struct point {int x, y;};
+static struct point const zero = {0,0};
+/* AIX XL C 1.02.0.0 rejects this.
+ It does not let you subtract one const X* pointer from another in an arm
+ of an if-expression whose if-part is not a constant expression */
+const char *g = "string";
+ccp = &g + (g ? g-g : 0);
+/* HPUX 7.0 cc rejects these. */
+++ccp;
+p = (char**) ccp;
+ccp = (char const *const *) p;
+{ /* SCO 3.2v4 cc rejects this. */
+ char *t;
+ char const *s = 0 ? (char *) 0 : (char const *) 0;
+
+ *t++ = 0;
+}
+{ /* Someone thinks the Sun supposedly-ANSI compiler will reject this. */
+ int x[] = {25, 17};
+ const int *foo = &x[0];
+ ++foo;
+}
+{ /* Sun SC1.0 ANSI compiler rejects this -- but not the above. */
+ typedef const int *iptr;
+ iptr p = 0;
+ ++p;
+}
+{ /* AIX XL C 1.02.0.0 rejects this saying
+ "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
+ struct s { int j; const int *ap[3]; };
+ struct s *b; b->j = 5;
+}
+{ /* ULTRIX-32 V3.1 (Rev 9) vcc rejects this */
+ const int foo = 10;
+}
+
+; return 0; }
+EOF
+if { (eval echo configure:2473: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_c_const=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_c_const=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_c_const" 1>&6
+if test $ac_cv_c_const = no; then
+ cat >> confdefs.h <<\EOF
+#define const
+EOF
+
+fi
+
+echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6
+echo "configure:2494: checking for uid_t in sys/types.h" >&5
+if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2499 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "uid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_uid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_uid_t=no
+fi
+rm -f conftest*
+
+fi
+
+echo "$ac_t""$ac_cv_type_uid_t" 1>&6
+if test $ac_cv_type_uid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define uid_t int
+EOF
+
+ cat >> confdefs.h <<\EOF
+#define gid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for off_t""... $ac_c" 1>&6
+echo "configure:2528: checking for off_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_off_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2533 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])off_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_off_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_off_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_off_t" 1>&6
+if test $ac_cv_type_off_t = no; then
+ cat >> confdefs.h <<\EOF
+#define off_t long
+EOF
+
+fi
+
+echo $ac_n "checking for pid_t""... $ac_c" 1>&6
+echo "configure:2561: checking for pid_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2566 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])pid_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_pid_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_pid_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_pid_t" 1>&6
+if test $ac_cv_type_pid_t = no; then
+ cat >> confdefs.h <<\EOF
+#define pid_t int
+EOF
+
+fi
+
+echo $ac_n "checking for size_t""... $ac_c" 1>&6
+echo "configure:2594: checking for size_t" >&5
+if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2599 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#if STDC_HEADERS
+#include <stdlib.h>
+#include <stddef.h>
+#endif
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "(^|[^a-zA-Z_0-9])size_t[^a-zA-Z_0-9]" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_size_t=yes
+else
+ rm -rf conftest*
+ ac_cv_type_size_t=no
+fi
+rm -f conftest*
+
+fi
+echo "$ac_t""$ac_cv_type_size_t" 1>&6
+if test $ac_cv_type_size_t = no; then
+ cat >> confdefs.h <<\EOF
+#define size_t unsigned
+EOF
+
+fi
+
+echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
+echo "configure:2627: checking whether time.h and sys/time.h may both be included" >&5
+if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2632 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <sys/time.h>
+#include <time.h>
+int main() {
+struct tm *tp;
+; return 0; }
+EOF
+if { (eval echo configure:2641: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_header_time=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_header_time=no
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_header_time" 1>&6
+if test $ac_cv_header_time = yes; then
+ cat >> confdefs.h <<\EOF
+#define TIME_WITH_SYS_TIME 1
+EOF
+
+fi
+
+echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
+echo "configure:2662: checking whether struct tm is in sys/time.h or time.h" >&5
+if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2667 "configure"
+#include "confdefs.h"
+#include <sys/types.h>
+#include <time.h>
+int main() {
+struct tm *tp; tp->tm_sec;
+; return 0; }
+EOF
+if { (eval echo configure:2675: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+ rm -rf conftest*
+ ac_cv_struct_tm=time.h
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ ac_cv_struct_tm=sys/time.h
+fi
+rm -f conftest*
+fi
+
+echo "$ac_t""$ac_cv_struct_tm" 1>&6
+if test $ac_cv_struct_tm = sys/time.h; then
+ cat >> confdefs.h <<\EOF
+#define TM_IN_SYS_TIME 1
+EOF
+
+fi
+
+
+echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6
+echo "configure:2697: checking type of array argument to getgroups" >&5
+if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_type_getgroups=cross
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2705 "configure"
+#include "confdefs.h"
+
+/* Thanks to Mike Rendell for this test. */
+#include <sys/types.h>
+#define NGID 256
+#undef MAX
+#define MAX(x, y) ((x) > (y) ? (x) : (y))
+main()
+{
+ gid_t gidset[NGID];
+ int i, n;
+ union { gid_t gval; long lval; } val;
+
+ val.lval = -1;
+ for (i = 0; i < NGID; i++)
+ gidset[i] = val.gval;
+ n = getgroups (sizeof (gidset) / MAX (sizeof (int), sizeof (gid_t)) - 1,
+ gidset);
+ /* Exit non-zero if getgroups seems to require an array of ints. This
+ happens when gid_t is short but getgroups modifies an array of ints. */
+ exit ((n > 0 && gidset[n] != val.gval) ? 1 : 0);
+}
+
+EOF
+if { (eval echo configure:2730: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_type_getgroups=gid_t
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_type_getgroups=int
+fi
+rm -fr conftest*
+fi
+
+if test $ac_cv_type_getgroups = cross; then
+ cat > conftest.$ac_ext <<EOF
+#line 2744 "configure"
+#include "confdefs.h"
+#include <unistd.h>
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "getgroups.*int.*gid_t" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_type_getgroups=gid_t
+else
+ rm -rf conftest*
+ ac_cv_type_getgroups=int
+fi
+rm -f conftest*
+
+fi
+fi
+
+echo "$ac_t""$ac_cv_type_getgroups" 1>&6
+cat >> confdefs.h <<EOF
+#define GETGROUPS_T $ac_cv_type_getgroups
+EOF
+
+
+if test $ac_cv_prog_gcc = yes; then
+ echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6
+echo "configure:2769: checking whether ${CC-cc} needs -traditional" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ ac_pattern="Autoconf.*'x'"
+ cat > conftest.$ac_ext <<EOF
+#line 2775 "configure"
+#include "confdefs.h"
+#include <sgtty.h>
+Autoconf TIOCGETP
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+else
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=no
+fi
+rm -f conftest*
+
+
+ if test $ac_cv_prog_gcc_traditional = no; then
+ cat > conftest.$ac_ext <<EOF
+#line 2793 "configure"
+#include "confdefs.h"
+#include <termio.h>
+Autoconf TCGETA
+EOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ egrep "$ac_pattern" >/dev/null 2>&1; then
+ rm -rf conftest*
+ ac_cv_prog_gcc_traditional=yes
+fi
+rm -f conftest*
+
+ fi
+fi
+
+echo "$ac_t""$ac_cv_prog_gcc_traditional" 1>&6
+ if test $ac_cv_prog_gcc_traditional = yes; then
+ CC="$CC -traditional"
+ fi
+fi
+
+echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6
+echo "configure:2815: checking for 8-bit clean memcmp" >&5
+if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test "$cross_compiling" = yes; then
+ ac_cv_func_memcmp_clean=no
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2823 "configure"
+#include "confdefs.h"
+
+main()
+{
+ char c0 = 0x40, c1 = 0x80, c2 = 0x81;
+ exit(memcmp(&c0, &c2, 1) < 0 && memcmp(&c1, &c2, 1) < 0 ? 0 : 1);
+}
+
+EOF
+if { (eval echo configure:2833: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+then
+ ac_cv_func_memcmp_clean=yes
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -fr conftest*
+ ac_cv_func_memcmp_clean=no
+fi
+rm -fr conftest*
+fi
+
+fi
+
+echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
+test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
+
+echo $ac_n "checking for vprintf""... $ac_c" 1>&6
+echo "configure:2851: checking for vprintf" >&5
+if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2856 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char vprintf(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char vprintf();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_vprintf) || defined (__stub___vprintf)
+choke me
+#else
+vprintf();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_vprintf=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'vprintf`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_VPRINTF 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test "$ac_cv_func_vprintf" != yes; then
+echo $ac_n "checking for _doprnt""... $ac_c" 1>&6
+echo "configure:2903: checking for _doprnt" >&5
+if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2908 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char _doprnt(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char _doprnt();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub__doprnt) || defined (__stub____doprnt)
+choke me
+#else
+_doprnt();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2931: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func__doprnt=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'_doprnt`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ cat >> confdefs.h <<\EOF
+#define HAVE_DOPRNT 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+fi
+
+for ac_func in gethostname gettimeofday mkdir select strcspn strdup strerror strspn strstr strtol uname
+do
+echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
+echo "configure:2958: checking for $ac_func" >&5
+if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 2963 "configure"
+#include "confdefs.h"
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $ac_func(); below. */
+#include <assert.h>
+/* Override any gcc2 internal prototype to avoid an error. */
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char $ac_func();
+
+int main() {
+
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined (__stub_$ac_func) || defined (__stub___$ac_func)
+choke me
+#else
+$ac_func();
+#endif
+
+; return 0; }
+EOF
+if { (eval echo configure:2986: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=yes"
+else
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_func_$ac_func=no"
+fi
+rm -f conftest*
+fi
+
+if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_func=HAVE_`echo $ac_func | tr 'abcdefghijklmnopqrstuvwxyz' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_func 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
+
+# Extract the first word of "sgml2txt", so it can be a program name with args.
+set dummy sgml2txt; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3014: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HAVE_SGML2TXT'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$HAVE_SGML2TXT"; then
+ ac_cv_prog_HAVE_SGML2TXT="$HAVE_SGML2TXT" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_HAVE_SGML2TXT="yes"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_HAVE_SGML2TXT" && ac_cv_prog_HAVE_SGML2TXT="no"
+fi
+fi
+HAVE_SGML2TXT="$ac_cv_prog_HAVE_SGML2TXT"
+if test -n "$HAVE_SGML2TXT"; then
+ echo "$ac_t""$HAVE_SGML2TXT" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "sgml2html", so it can be a program name with args.
+set dummy sgml2html; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3044: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HAVE_SGML2HTML'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$HAVE_SGML2HTML"; then
+ ac_cv_prog_HAVE_SGML2HTML="$HAVE_SGML2HTML" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_HAVE_SGML2HTML="yes"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_HAVE_SGML2HTML" && ac_cv_prog_HAVE_SGML2HTML="no"
+fi
+fi
+HAVE_SGML2HTML="$ac_cv_prog_HAVE_SGML2HTML"
+if test -n "$HAVE_SGML2HTML"; then
+ echo "$ac_t""$HAVE_SGML2HTML" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+# Extract the first word of "sgml2latex", so it can be a program name with args.
+set dummy sgml2latex; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3074: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HAVE_SGML2LATEX'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$HAVE_SGML2LATEX"; then
+ ac_cv_prog_HAVE_SGML2LATEX="$HAVE_SGML2LATEX" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_HAVE_SGML2LATEX="yes"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_HAVE_SGML2LATEX" && ac_cv_prog_HAVE_SGML2LATEX="no"
+fi
+fi
+HAVE_SGML2LATEX="$ac_cv_prog_HAVE_SGML2LATEX"
+if test -n "$HAVE_SGML2LATEX"; then
+ echo "$ac_t""$HAVE_SGML2LATEX" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+if test $HAVE_SGML2LATEX = "yes" ; then
+ if sgml2latex -h | grep -e --paper | grep ' -p ' > /dev/null ; then
+ PSER="sgml2latex -o ps"
+ else
+ PSER="sgml2latex -p"
+ fi
+else
+ # Extract the first word of "sgml2ps", so it can be a program name with args.
+set dummy sgml2ps; ac_word=$2
+echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
+echo "configure:3111: checking for $ac_word" >&5
+if eval "test \"`echo '$''{'ac_cv_prog_HAVE_SGML2PS'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ if test -n "$HAVE_SGML2PS"; then
+ ac_cv_prog_HAVE_SGML2PS="$HAVE_SGML2PS" # Let the user override the test.
+else
+ IFS="${IFS= }"; ac_save_ifs="$IFS"; IFS=":"
+ ac_dummy="$PATH"
+ for ac_dir in $ac_dummy; do
+ test -z "$ac_dir" && ac_dir=.
+ if test -f $ac_dir/$ac_word; then
+ ac_cv_prog_HAVE_SGML2PS="yes"
+ break
+ fi
+ done
+ IFS="$ac_save_ifs"
+ test -z "$ac_cv_prog_HAVE_SGML2PS" && ac_cv_prog_HAVE_SGML2PS="no"
+fi
+fi
+HAVE_SGML2PS="$ac_cv_prog_HAVE_SGML2PS"
+if test -n "$HAVE_SGML2PS"; then
+ echo "$ac_t""$HAVE_SGML2PS" 1>&6
+else
+ echo "$ac_t""no" 1>&6
+fi
+
+ if test $HAVE_SGML2PS = yes ; then
+ PSER="sgml2ps"
+ fi
+fi
+
+
+trap '' 1 2 15
+cat > confcache <<\EOF
+# This file is a shell script that caches the results of configure
+# tests run on this system so they can be shared between configure
+# scripts and configure runs. It is not useful on other systems.
+# If it contains results you don't want to keep, you may remove or edit it.
+#
+# By default, configure uses ./config.cache as the cache file,
+# creating it if it does not exist already. You can give configure
+# the --cache-file=FILE option to use a different cache file; that is
+# what configure does when it calls configure scripts in
+# subdirectories, so they share the cache.
+# Giving --cache-file=/dev/null disables caching, for debugging configure.
+# config.status only pays attention to the cache file if you give it the
+# --recheck option to rerun configure.
+#
+EOF
+# The following way of writing the cache mishandles newlines in values,
+# but we know of no workaround that is simple, portable, and efficient.
+# So, don't put newlines in cache variables' values.
+# Ultrix sh set writes to stderr and can't be redirected directly,
+# and sets the high bit in the cache file unless we assign to the vars.
+(set) 2>&1 |
+ case `(ac_space=' '; set | grep ac_space) 2>&1` in
+ *ac_space=\ *)
+ # `set' does not quote correctly, so add quotes (double-quote substitution
+ # turns \\\\ into \\, and sed turns \\ into \).
+ sed -n \
+ -e "s/'/'\\\\''/g" \
+ -e "s/^\\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\\)=\\(.*\\)/\\1=\${\\1='\\2'}/p"
+ ;;
+ *)
+ # `set' quotes correctly as required by POSIX, so do not add quotes.
+ sed -n -e 's/^\([a-zA-Z0-9_]*_cv_[a-zA-Z0-9_]*\)=\(.*\)/\1=${\1=\2}/p'
+ ;;
+ esac >> confcache
+if cmp -s $cache_file confcache; then
+ :
+else
+ if test -w $cache_file; then
+ echo "updating cache $cache_file"
+ cat confcache > $cache_file
+ else
+ echo "not updating unwritable cache $cache_file"
+ fi
+fi
+rm -f confcache
+
+trap 'rm -fr conftest* confdefs* core core.* *.core $ac_clean_files; exit 1' 1 2 15
+
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+# Let make expand exec_prefix.
+test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+
+# Any assignment to VPATH causes Sun make to only execute
+# the first set of double-colon rules, so remove it if not needed.
+# If there is a colon in the path, we need to keep it.
+if test "x$srcdir" = x.; then
+ ac_vpsub='/^[ ]*VPATH[ ]*=[^:]*$/d'
+fi
+
+trap 'rm -f $CONFIG_STATUS conftest*; exit 1' 1 2 15
+
+DEFS=-DHAVE_CONFIG_H
+
+# Without the "./", some shells look in PATH for config.status.
+: ${CONFIG_STATUS=./config.status}
+
+echo creating $CONFIG_STATUS
+rm -f $CONFIG_STATUS
+cat > $CONFIG_STATUS <<EOF
+#! /bin/sh
+# Generated automatically by configure.
+# Run this file to recreate the current configuration.
+# This directory was configured as follows,
+# on host `(hostname || uname -n) 2>/dev/null | sed 1q`:
+#
+# $0 $ac_configure_args
+#
+# Compiler output produced by configure, useful for debugging
+# configure, is in ./config.log if it exists.
+
+ac_cs_usage="Usage: $CONFIG_STATUS [--recheck] [--version] [--help]"
+for ac_option
+do
+ case "\$ac_option" in
+ -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r)
+ echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion"
+ exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;;
+ -version | --version | --versio | --versi | --vers | --ver | --ve | --v)
+ echo "$CONFIG_STATUS generated by autoconf version 2.13"
+ exit 0 ;;
+ -help | --help | --hel | --he | --h)
+ echo "\$ac_cs_usage"; exit 0 ;;
+ *) echo "\$ac_cs_usage"; exit 1 ;;
+ esac
+done
+
+ac_given_srcdir=$srcdir
+
+trap 'rm -fr `echo "Make.Rules _pam_aconf.h" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+# Protect against being on the right side of a sed subst in config.status.
+sed 's/%@/@@/; s/@%/@@/; s/%g\$/@g/; /@g\$/s/[\\\\&%]/\\\\&/g;
+ s/@@/%@/; s/@@/@%/; s/@g\$/%g/' > conftest.subs <<\\CEOF
+$ac_vpsub
+$extrasub
+s%@SHELL@%$SHELL%g
+s%@CFLAGS@%$CFLAGS%g
+s%@CPPFLAGS@%$CPPFLAGS%g
+s%@CXXFLAGS@%$CXXFLAGS%g
+s%@FFLAGS@%$FFLAGS%g
+s%@DEFS@%$DEFS%g
+s%@LDFLAGS@%$LDFLAGS%g
+s%@LIBS@%$LIBS%g
+s%@exec_prefix@%$exec_prefix%g
+s%@prefix@%$prefix%g
+s%@program_transform_name@%$program_transform_name%g
+s%@bindir@%$bindir%g
+s%@sbindir@%$sbindir%g
+s%@libexecdir@%$libexecdir%g
+s%@datadir@%$datadir%g
+s%@sysconfdir@%$sysconfdir%g
+s%@sharedstatedir@%$sharedstatedir%g
+s%@localstatedir@%$localstatedir%g
+s%@libdir@%$libdir%g
+s%@includedir@%$includedir%g
+s%@oldincludedir@%$oldincludedir%g
+s%@infodir@%$infodir%g
+s%@mandir@%$mandir%g
+s%@LIBPAM_VERSION_MAJOR@%$LIBPAM_VERSION_MAJOR%g
+s%@LIBPAM_VERSION_MINOR@%$LIBPAM_VERSION_MINOR%g
+s%@CC@%$CC%g
+s%@CONF_CFLAGS@%$CONF_CFLAGS%g
+s%@MKDIR@%$MKDIR%g
+s%@LOCALSRCDIR@%$LOCALSRCDIR%g
+s%@OS@%$OS%g
+s%@DYNTYPE@%$DYNTYPE%g
+s%@USESONAME@%$USESONAME%g
+s%@NEEDSONAME@%$NEEDSONAME%g
+s%@SHLIBMODE@%$SHLIBMODE%g
+s%@INSTALL@%$INSTALL%g
+s%@YACC@%$YACC%g
+s%@LEX@%$LEX%g
+s%@LEXLIB@%$LEXLIB%g
+s%@LN_S@%$LN_S%g
+s%@SET_MAKE@%$SET_MAKE%g
+s%@WITH_DEBUG@%$WITH_DEBUG%g
+s%@WITH_LIBDEBUG@%$WITH_LIBDEBUG%g
+s%@FAKEROOT@%$FAKEROOT%g
+s%@SECUREDIR@%$SECUREDIR%g
+s%@SCONFIGDIR@%$SCONFIGDIR%g
+s%@SUPLEMENTED@%$SUPLEMENTED%g
+s%@INCLUDEDIR@%$INCLUDEDIR%g
+s%@WITH_PAMLOCKING@%$WITH_PAMLOCKING%g
+s%@PAM_READ_BOTH_CONFS@%$PAM_READ_BOTH_CONFS%g
+s%@STATIC_LIBPAM@%$STATIC_LIBPAM%g
+s%@DYNAMIC_LIBPAM@%$DYNAMIC_LIBPAM%g
+s%@DYNAMIC@%$DYNAMIC%g
+s%@STATIC@%$STATIC%g
+s%@WITH_LCKPWDF@%$WITH_LCKPWDF%g
+s%@CPP@%$CPP%g
+s%@PAM_NEEDS_LIBC@%$PAM_NEEDS_LIBC%g
+s%@HAVE_LCKPWDF@%$HAVE_LCKPWDF%g
+s%@LIBDL@%$LIBDL%g
+s%@HAVE_LIBCRACK@%$HAVE_LIBCRACK%g
+s%@HAVE_LIBCRYPT@%$HAVE_LIBCRYPT%g
+s%@HAVE_LIBUTIL@%$HAVE_LIBUTIL%g
+s%@HAVE_LIBNDBM@%$HAVE_LIBNDBM%g
+s%@HAVE_LIBDB@%$HAVE_LIBDB%g
+s%@HAVE_LIBFL@%$HAVE_LIBFL%g
+s%@HAVE_LIBNSL@%$HAVE_LIBNSL%g
+s%@HAVE_LIBPWDB@%$HAVE_LIBPWDB%g
+s%@HAVE_NDBM_H@%$HAVE_NDBM_H%g
+s%@CRACKLIB_DICTPATH@%$CRACKLIB_DICTPATH%g
+s%@OS_CFLAGS@%$OS_CFLAGS%g
+s%@WARNINGS@%$WARNINGS%g
+s%@PIC@%$PIC%g
+s%@LD@%$LD%g
+s%@LD_D@%$LD_D%g
+s%@LD_L@%$LD_L%g
+s%@RANLIB@%$RANLIB%g
+s%@STRIP@%$STRIP%g
+s%@CC_STATIC@%$CC_STATIC%g
+s%@LIBOBJS@%$LIBOBJS%g
+s%@HAVE_SGML2TXT@%$HAVE_SGML2TXT%g
+s%@HAVE_SGML2HTML@%$HAVE_SGML2HTML%g
+s%@HAVE_SGML2LATEX@%$HAVE_SGML2LATEX%g
+s%@HAVE_SGML2PS@%$HAVE_SGML2PS%g
+s%@PSER@%$PSER%g
+
+CEOF
+EOF
+
+cat >> $CONFIG_STATUS <<\EOF
+
+# Split the substitutions into bite-sized pieces for seds with
+# small command number limits, like on Digital OSF/1 and HP-UX.
+ac_max_sed_cmds=90 # Maximum number of lines to put in a sed script.
+ac_file=1 # Number of current file.
+ac_beg=1 # First line for current file.
+ac_end=$ac_max_sed_cmds # Line after last line for current file.
+ac_more_lines=:
+ac_sed_cmds=""
+while $ac_more_lines; do
+ if test $ac_beg -gt 1; then
+ sed "1,${ac_beg}d; ${ac_end}q" conftest.subs > conftest.s$ac_file
+ else
+ sed "${ac_end}q" conftest.subs > conftest.s$ac_file
+ fi
+ if test ! -s conftest.s$ac_file; then
+ ac_more_lines=false
+ rm -f conftest.s$ac_file
+ else
+ if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds="sed -f conftest.s$ac_file"
+ else
+ ac_sed_cmds="$ac_sed_cmds | sed -f conftest.s$ac_file"
+ fi
+ ac_file=`expr $ac_file + 1`
+ ac_beg=$ac_end
+ ac_end=`expr $ac_end + $ac_max_sed_cmds`
+ fi
+done
+if test -z "$ac_sed_cmds"; then
+ ac_sed_cmds=cat
+fi
+EOF
+
+cat >> $CONFIG_STATUS <<EOF
+
+CONFIG_FILES=\${CONFIG_FILES-"Make.Rules"}
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ # Adjust a relative srcdir, top_srcdir, and INSTALL for subdirectories.
+
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ ac_dir_suffix="/`echo $ac_dir|sed 's%^\./%%'`"
+ # A "../" for each directory in $ac_dir_suffix.
+ ac_dots=`echo $ac_dir_suffix|sed 's%/[^/]*%../%g'`
+ else
+ ac_dir_suffix= ac_dots=
+ fi
+
+ case "$ac_given_srcdir" in
+ .) srcdir=.
+ if test -z "$ac_dots"; then top_srcdir=.
+ else top_srcdir=`echo $ac_dots|sed 's%/$%%'`; fi ;;
+ /*) srcdir="$ac_given_srcdir$ac_dir_suffix"; top_srcdir="$ac_given_srcdir" ;;
+ *) # Relative path.
+ srcdir="$ac_dots$ac_given_srcdir$ac_dir_suffix"
+ top_srcdir="$ac_dots$ac_given_srcdir" ;;
+ esac
+
+
+ echo creating "$ac_file"
+ rm -f "$ac_file"
+ configure_input="Generated automatically from `echo $ac_file_in|sed 's%.*/%%'` by configure."
+ case "$ac_file" in
+ *Makefile*) ac_comsub="1i\\
+# $configure_input" ;;
+ *) ac_comsub= ;;
+ esac
+
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ sed -e "$ac_comsub
+s%@configure_input@%$configure_input%g
+s%@srcdir@%$srcdir%g
+s%@top_srcdir@%$top_srcdir%g
+" $ac_file_inputs | (eval "$ac_sed_cmds") > $ac_file
+fi; done
+rm -f conftest.s*
+
+# These sed commands are passed to sed as "A NAME B NAME C VALUE D", where
+# NAME is the cpp macro being defined and VALUE is the value it is being given.
+#
+# ac_d sets the value in "#define NAME VALUE" lines.
+ac_dA='s%^\([ ]*\)#\([ ]*define[ ][ ]*\)'
+ac_dB='\([ ][ ]*\)[^ ]*%\1#\2'
+ac_dC='\3'
+ac_dD='%g'
+# ac_u turns "#undef NAME" with trailing blanks into "#define NAME VALUE".
+ac_uA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_uB='\([ ]\)%\1#\2define\3'
+ac_uC=' '
+ac_uD='\4%g'
+# ac_e turns "#undef NAME" without trailing blanks into "#define NAME VALUE".
+ac_eA='s%^\([ ]*\)#\([ ]*\)undef\([ ][ ]*\)'
+ac_eB='$%\1#\2define\3'
+ac_eC=' '
+ac_eD='%g'
+
+if test "${CONFIG_HEADERS+set}" != set; then
+EOF
+cat >> $CONFIG_STATUS <<EOF
+ CONFIG_HEADERS="_pam_aconf.h"
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+fi
+for ac_file in .. $CONFIG_HEADERS; do if test "x$ac_file" != x..; then
+ # Support "outfile[:infile[:infile...]]", defaulting infile="outfile.in".
+ case "$ac_file" in
+ *:*) ac_file_in=`echo "$ac_file"|sed 's%[^:]*:%%'`
+ ac_file=`echo "$ac_file"|sed 's%:.*%%'` ;;
+ *) ac_file_in="${ac_file}.in" ;;
+ esac
+
+ echo creating $ac_file
+
+ rm -f conftest.frag conftest.in conftest.out
+ ac_file_inputs=`echo $ac_file_in|sed -e "s%^%$ac_given_srcdir/%" -e "s%:% $ac_given_srcdir/%g"`
+ cat $ac_file_inputs > conftest.in
+
+EOF
+
+# Transform confdefs.h into a sed script conftest.vals that substitutes
+# the proper values into config.h.in to produce config.h. And first:
+# Protect against being on the right side of a sed subst in config.status.
+# Protect against being in an unquoted here document in config.status.
+rm -f conftest.vals
+cat > conftest.hdr <<\EOF
+s/[\\&%]/\\&/g
+s%[\\$`]%\\&%g
+s%#define \([A-Za-z_][A-Za-z0-9_]*\) *\(.*\)%${ac_dA}\1${ac_dB}\1${ac_dC}\2${ac_dD}%gp
+s%ac_d%ac_u%gp
+s%ac_u%ac_e%gp
+EOF
+sed -n -f conftest.hdr confdefs.h > conftest.vals
+rm -f conftest.hdr
+
+# This sed command replaces #undef with comments. This is necessary, for
+# example, in the case of _POSIX_SOURCE, which is predefined and required
+# on some systems where configure will not decide to define it.
+cat >> conftest.vals <<\EOF
+s%^[ ]*#[ ]*undef[ ][ ]*[a-zA-Z_][a-zA-Z_0-9]*%/* & */%
+EOF
+
+# Break up conftest.vals because some shells have a limit on
+# the size of here documents, and old seds have small limits too.
+
+rm -f conftest.tail
+while :
+do
+ ac_lines=`grep -c . conftest.vals`
+ # grep -c gives empty output for an empty file on some AIX systems.
+ if test -z "$ac_lines" || test "$ac_lines" -eq 0; then break; fi
+ # Write a limited-size here document to conftest.frag.
+ echo ' cat > conftest.frag <<CEOF' >> $CONFIG_STATUS
+ sed ${ac_max_here_lines}q conftest.vals >> $CONFIG_STATUS
+ echo 'CEOF
+ sed -f conftest.frag conftest.in > conftest.out
+ rm -f conftest.in
+ mv conftest.out conftest.in
+' >> $CONFIG_STATUS
+ sed 1,${ac_max_here_lines}d conftest.vals > conftest.tail
+ rm -f conftest.vals
+ mv conftest.tail conftest.vals
+done
+rm -f conftest.vals
+
+cat >> $CONFIG_STATUS <<\EOF
+ rm -f conftest.frag conftest.h
+ echo "/* $ac_file. Generated automatically by configure. */" > conftest.h
+ cat conftest.in >> conftest.h
+ rm -f conftest.in
+ if cmp -s $ac_file conftest.h 2>/dev/null; then
+ echo "$ac_file is unchanged"
+ rm -f conftest.h
+ else
+ # Remove last slash and all that follows it. Not all systems have dirname.
+ ac_dir=`echo $ac_file|sed 's%/[^/][^/]*$%%'`
+ if test "$ac_dir" != "$ac_file" && test "$ac_dir" != .; then
+ # The file is in a subdirectory.
+ test ! -d "$ac_dir" && mkdir "$ac_dir"
+ fi
+ rm -f $ac_file
+ mv conftest.h $ac_file
+ fi
+fi; done
+
+EOF
+cat >> $CONFIG_STATUS <<EOF
+
+EOF
+cat >> $CONFIG_STATUS <<\EOF
+
+exit 0
+EOF
+chmod +x $CONFIG_STATUS
+rm -fr confdefs* $ac_clean_files
+test "$no_create" = yes || ${CONFIG_SHELL-/bin/sh} $CONFIG_STATUS || exit 1
+
diff --git a/contrib/libpam/configure.in b/contrib/libpam/configure.in
new file mode 100644
index 000000000000..fb3752db8dc8
--- /dev/null
+++ b/contrib/libpam/configure.in
@@ -0,0 +1,339 @@
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(conf/pam_conv1/pam_conv.y)
+
+dnl The configuration header file
+AC_CONFIG_HEADER(_pam_aconf.h)
+
+dnl
+dnl Release specific
+dnl
+
+LIBPAM_VERSION_MAJOR=0
+LIBPAM_VERSION_MINOR=75
+
+AC_SUBST(LIBPAM_VERSION_MAJOR)
+AC_SUBST(LIBPAM_VERSION_MINOR)
+AC_DEFINE(LIBPAM_VERSION_MAJOR)
+AC_DEFINE(LIBPAM_VERSION_MINOR)
+
+dnl
+dnl By default, everything under PAM is installed under the root fs.
+dnl
+
+AC_PREFIX_DEFAULT()
+
+dnl
+dnl Rules needed for the following (hardcoded Linux defaults for now)
+dnl
+
+CC=gcc ; AC_SUBST(CC)
+CONF_CFLAGS= ; AC_SUBST(CONF_CFLAGS)
+MKDIR="mkdir -p" ; AC_SUBST(MKDIR)
+LOCALSRCDIR=`/bin/pwd` ; AC_SUBST(LOCALSRCDIR)
+OS=`uname|sed -e 'y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/'`
+AC_SUBST(OS)
+
+dnl These are most likely platform specific - I think HPUX differs
+DYNTYPE=so ; AC_SUBST(DYNTYPE)
+USESONAME=yes ; AC_SUBST(USESONAME)
+NEEDSONAME=yes ; AC_SUBST(NEEDSONAME)
+SHLIBMODE=755 ; AC_SUBST(SHLIBMODE)
+
+dnl ### Should enable this INSTALL detection.
+dnl ### Would need to distribute GNU's config.guess and config.sub
+dnl AC_PROG_INSTALL
+INSTALL=/usr/bin/install ; AC_SUBST(INSTALL)
+
+dnl Checks for programs.
+AC_PROG_CC
+dnl ### AC_PROG_CXX
+AC_PROG_YACC
+AC_PROG_LEX
+dnl AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+dnl
+dnl options and defaults
+dnl
+
+dnl lots of debugging information goes to /tmp/pam-debug.log
+AC_ARG_ENABLE(debug,
+[ --enable-debug qspecify you are building with debugging on],
+ WITH_DEBUG=yes ; AC_DEFINE(DEBUG) , WITH_DEBUG=no)
+AC_SUBST(WITH_DEBUG)
+
+dnl build specially named libraries (for debugging purposes)
+AC_ARG_ENABLE(libdebug,
+[ --enable-libdebug specify you are building debugging libraries],
+ WITH_LIBDEBUG=yes ; AC_DEFINE(WITH_LIBDEBUG) , WITH_LIBDEBUG=no)
+AC_SUBST(WITH_LIBDEBUG)
+
+dnl packaging convenience
+AC_ARG_ENABLE(fakeroot,
+[ --enable-fakeroot=<path to packaging directory>], FAKEROOT=$enableval)
+AC_SUBST(FAKEROOT)
+
+AC_ARG_ENABLE(securedir,
+[ --enable-securedir=<path to location of PAMs> [default \$libdir/security]],
+ SECUREDIR=$enableval, SECUREDIR=$libdir/security)
+AC_SUBST(SECUREDIR)
+
+AC_ARG_ENABLE(sconfigdir,
+[ --enable-sconfigdir=<path to module conf files> [default \$sysconfdir/security]],
+ SCONFIGDIR=$enableval, SCONFIGDIR=$sysconfdir/security)
+AC_SUBST(SCONFIGDIR)
+
+AC_ARG_ENABLE(suplementedir,
+[ --enable-suplementedir=<path to module helper binaries> [default \$sbindir]],
+ SUPLEMENTED=$enableval, SUPLEMENTED=$sbindir)
+AC_SUBST(SUPLEMENTED)
+
+AC_ARG_ENABLE(includedir,
+[ --enable-includedir=<path to include location> - where to put <security>],
+ INCLUDEDIR=$enableval, INCLUDEDIR=/usr/include)
+AC_SUBST(INCLUDEDIR)
+
+AC_ARG_ENABLE(pamlocking,
+[ --enable-pamlocking configure libpam to observe a global authentication lock],
+ WITH_PAMLOCKING=yes ; AC_DEFINE(PAM_LOCKING) , WITH_PAMLOCKING=no)
+AC_SUBST(WITH_PAMLOCKING)
+
+AC_ARG_ENABLE(uglyhack,
+[ --enable-uglyhack configure libpam to try to honor old pam_strerror syntax],
+ AC_DEFINE(UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT))
+
+AC_ARG_ENABLE(read-both-confs,
+[ --enable-read-both-confs read both /etc/pam.d and /etc/pam.conf files],
+ AC_DEFINE(PAM_READ_BOTH_CONFS))
+AC_SUBST(PAM_READ_BOTH_CONFS)
+
+AC_ARG_ENABLE(static-libpam, [ --enable-static-libpam build a libpam.a library],
+ STATIC_LIBPAM=yes , STATIC_LIBPAM=no)
+AC_SUBST(STATIC_LIBPAM)
+
+AC_ARG_ENABLE(dynamic-libpam,
+[ --disable-dynamic-libpam do not build a shared libpam library],
+ DYNAMIC_LIBPAM=no, DYNAMIC_LIBPAM=yes)
+AC_SUBST(DYNAMIC_LIBPAM)
+
+DYNAMIC=-DPAM_DYNAMIC
+AC_SUBST(DYNAMIC)
+
+AC_ARG_ENABLE(static-modules,
+[ --enable-static-modules do not make the modules dynamically loadable],
+ STATIC=-DPAM_STATIC)
+AC_SUBST(STATIC)
+
+AC_ARG_ENABLE(lckpwdf,
+[ --disable-lckpwdf do not use the lckpwdf function],
+ WITH_LCKPWDF=no, WITH_LCKPWDF=yes)
+AC_SUBST(WITH_LCKPWDF)
+
+AC_CHECK_HEADERS(paths.h)
+AC_ARG_WITH(mailspool,
+[ --with-mailspool path to mail spool directory
+ [default _PATH_MAILDIR if defined in paths.h, otherwise /var/spool/mail]],
+with_mailspool=${withval})
+if test x$with_mailspool != x ; then
+ pam_mail_spool="\"$with_mailspool\""
+else
+ AC_TRY_RUN([
+#include <paths.h>
+int main() {
+#ifdef _PATH_MAILDIR
+exit(0);
+#else
+exit(1);
+#endif
+}], pam_mail_spool="_PATH_MAILDIR",
+pam_mail_spool="\"/var/spool/mail\"",
+pam_mail_spool="\"/var/spool/mail\"")
+fi
+AC_DEFINE_UNQUOTED(PAM_PATH_MAILDIR, $pam_mail_spool)
+
+dnl Checks for libraries.
+AC_CHECK_LIB(c, __libc_sched_setscheduler, PAM_NEEDS_LIBC=, PAM_NEEDS_LIBC=-lc)
+AC_SUBST(PAM_NEEDS_LIBC)
+
+dnl Checks for the existence of lckpwdf in libc
+AC_CHECK_LIB(c, lckpwdf, HAVE_LCKPWDF=yes, HAVE_LCKPWDF=no)
+AC_SUBST(HAVE_LCKPWDF)
+
+dnl Checks for the existence of libdl - on BSD its part of libc
+AC_CHECK_LIB(dl, dlopen, LIBDL=-ldl)
+AC_SUBST(LIBDL)
+
+dnl
+dnl At least on Solaris, the existing libcrack must be dynamic.
+dnl Ought to introduce a check for this.
+dnl
+AC_CHECK_LIB(crack, FascistCheck, HAVE_LIBCRACK=yes ; AC_DEFINE(HAVE_LIBCRACK),
+ HAVE_LIBCRACK=no)
+AC_SUBST(HAVE_LIBCRACK)
+
+AC_CHECK_LIB(crypt, fcrypt, HAVE_LIBCRYPT=yes ; AC_DEFINE(HAVE_LIBCRYPT),
+ HAVE_LIBCRYPT=no)
+AC_SUBST(HAVE_LIBCRYPT)
+AC_CHECK_LIB(util, logwtmp, HAVE_LIBUTIL=yes ; AC_DEFINE(HAVE_LIBUTIL),
+ HAVE_LIBUTIL=no)
+AC_SUBST(HAVE_LIBUTIL)
+AC_CHECK_LIB(ndbm, dbm_store, HAVE_LIBNDBM=yes ; AC_DEFINE(HAVE_LIBNDBM),
+ HAVE_LIBNDBM=no)
+AC_SUBST(HAVE_LIBNDBM)
+AC_CHECK_LIB(db, dbm_store, HAVE_LIBDB=yes ; AC_DEFINE(HAVE_LIBDB),
+ HAVE_LIBDB=no)
+AC_SUBST(HAVE_LIBDB)
+AC_CHECK_LIB(fl, yylex, yyterminate, HAVE_LIBFL=yes ; AC_DEFINE(HAVE_LIBFL),
+ HAVE_LIBFL=no)
+AC_SUBST(HAVE_LIBFL)
+AC_CHECK_LIB(nsl, yp_maplist, HAVE_LIBNSL=yes ; AC_DEFINE(HAVE_LIBNSL),
+ HAVE_LIBNSL=no)
+AC_SUBST(HAVE_LIBNSL)
+AC_CHECK_LIB(pwdb, pwdb_db_name, HAVE_LIBPWDB=yes ; AC_DEFINE(HAVE_LIBPWDB),
+ HAVE_LIBPWDB=no)
+AC_SUBST(HAVE_LIBPWDB)
+
+dnl Checks for header files.
+AC_HEADER_DIRENT
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h termio.h unistd.h)
+
+dnl Linux wants features.h in some of the source files.
+AC_CHECK_HEADERS(features.h)
+
+dnl For module/pam_cracklib
+AC_CHECK_HEADERS(crypt.h)
+
+dnl For module/pam_userdb
+AC_CHECK_HEADERS(ndbm.h db.h)
+dnl I suspect the following two lines are a hack.
+HAVE_NDBM_H=$ac_cv_header_ndbm_h
+AC_SUBST(HAVE_NDBM_H)
+
+dnl For module/pam_lastlog
+AC_CHECK_HEADERS(lastlog.h utmp.h utmpx.h)
+
+dnl This following rule should be made conditional upon HAVE_LIBCRYPT
+dnl being found.
+
+dnl Look for cracklib dictionary
+AC_MSG_CHECKING(path to cracklib dictionary)
+DICT_DIR_CANDIDATES="/usr/lib /usr/share/dict /usr/share/lib \
+ /usr/local/lib /usr/local/share/lib"
+DICT_FILE_CANDIDATES="pw_dict cracklib_dict"
+CRACKLIB_DICTPATH=""
+for d in $DICT_DIR_CANDIDATES ; do
+ for f in $DICT_FILE_CANDIDATES ; do
+ if test -r $d/$f.hwm ; then
+ CRACKLIB_DICTPATH=$d/$f
+ break 2
+ elif test -r $d/dict/$f.hwm ; then
+ CRACKLIB_DICTPATH=$d/dict/$f
+ break 2
+ fi
+ done
+done
+if test -z "$CRACKLIB_DICTPATH" ; then
+ AC_MSG_RESULT(none found)
+else
+ AC_MSG_RESULT($CRACKLIB_DICTPATH)
+fi
+AC_SUBST(CRACKLIB_DICTPATH)
+
+dnl Set FLAGS, linker options etc. depending on C compiler.
+dnl gcc is tested and much preferred; others less so, if at all
+dnl
+dnl If compiling with gcc, linking is also supposed to be done with gcc;
+dnl since we use linker-specific arguments, we may not gain anything by
+dnl switching LD_L over, but I think we can use LD_D as-is.
+dnl
+dnl For the moment, gcc is enforced above at "CC=gcc".
+dnl
+dnl There is an issue over _POSIX_SOURCE _BSD_SOURCE and _GNU_SOURCE .
+dnl The original "Linux-PAM" had blanket inclusion. But portability
+dnl requires their default absence: if particular OSes require them,
+dnl this should be done selectively.
+
+GCC_WARNINGS="-Wall -Wwrite-strings \
+ -Wpointer-arith -Wcast-qual -Wcast-align \
+ -Wstrict-prototypes -Wmissing-prototypes \
+ -Wnested-externs -Winline -Wshadow"
+
+if test "$GCC" = yes; then
+###
+### Non-Linux needs attention on per-OS basis
+ OS_CFLAGS="-ansi -D_POSIX_SOURCE -pedantic"
+ WARNINGS="$GCC_WARNINGS"
+ PIC="-fPIC"
+#can/should we use LD=gcc ???
+ LD=ld
+ LD_D="gcc -shared -Xlinker -x"
+ LD_L="$LD -x -shared"
+ RANLIB=ranlib
+ STRIP=strip
+ CC_STATIC="-Xlinker -export-dynamic"
+else
+###
+### Non-gcc needs attention on per-OS basis
+###
+### [These are Solaris-C specific...]
+ OS_CFLAGS=""
+ WARNINGS=""
+ PIC="-K pic"
+ LD=ld
+ LD_D="cc -z text -G -R."
+ LD_L="$LD_D"
+ RANLIB=ranlib
+ STRIP=strip
+ CC_STATIC=
+fi
+
+AC_SUBST(OS_CFLAGS)
+AC_SUBST(WARNINGS)
+AC_SUBST(PIC)
+AC_SUBST(LD)
+AC_SUBST(LD_D)
+AC_SUBST(LD_L)
+AC_SUBST(RANLIB)
+AC_SUBST(STRIP)
+AC_SUBST(CC_STATIC)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_BIGENDIAN
+AC_C_CONST
+AC_TYPE_UID_T
+AC_TYPE_OFF_T
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+AC_STRUCT_TM
+
+dnl Checks for library functions.
+AC_TYPE_GETGROUPS
+AC_PROG_GCC_TRADITIONAL
+AC_FUNC_MEMCMP
+AC_FUNC_VPRINTF
+AC_CHECK_FUNCS(gethostname gettimeofday mkdir select strcspn strdup strerror strspn strstr strtol uname)
+
+dnl Checks for programs/utilities
+AC_CHECK_PROG(HAVE_SGML2TXT, sgml2txt, yes, no)
+AC_CHECK_PROG(HAVE_SGML2HTML, sgml2html, yes, no)
+AC_CHECK_PROG(HAVE_SGML2LATEX, sgml2latex, yes, no)
+if test $HAVE_SGML2LATEX = "yes" ; then
+ if sgml2latex -h | grep -e --paper | grep ' -p ' > /dev/null ; then
+ PSER="sgml2latex -o ps"
+ else
+ PSER="sgml2latex -p"
+ fi
+else
+ AC_CHECK_PROG(HAVE_SGML2PS, sgml2ps, yes, no)
+ if test $HAVE_SGML2PS = yes ; then
+ PSER="sgml2ps"
+ fi
+fi
+AC_SUBST(PSER)
+
+dnl Files to be created from when we run configure
+AC_OUTPUT(Make.Rules)
diff --git a/contrib/libpam/defs/debian.defs b/contrib/libpam/defs/debian.defs
new file mode 100644
index 000000000000..19ba46635ad1
--- /dev/null
+++ b/contrib/libpam/defs/debian.defs
@@ -0,0 +1,40 @@
+##
+# defs for Debian
+# Ben Collins <bcollins@debian.org>
+##
+# this file indicates the compiler and the various hardware/OS dependent
+# flags for installation. It also defines the various destinations of
+# installed files on the system.
+##
+
+CFLAGS := -O2 -I${shell pwd}/include # -D__NO_STRING_INLINES
+ifneq (,$(findstring $(DEB_BUILD_OPTIONS),debug DEBUG Debug))
+ CFLAGS += -g
+endif
+
+OS := $(shell dpkg-architecture -qDEB_BUILD_GNU_SYSTEM)
+ARCH := $(shell dpkg-architecture -qDEB_BUILD_GNU_CPU)
+CC := gcc
+INSTALL := install
+MKDIR := mkdir -p
+ULIBS :=
+LD := ld
+LD_D := gcc -shared -Xlinker -x
+LD_L := $(LD) -x -shared
+AR := ar -cr
+RANLIB := ranlib
+PREFIX :=
+LIBDIR := $(PREFIX)/lib
+USESONAME := yes
+SOSWITCH := -soname
+LINKLIBS := -lc -L${shell pwd}/libpam -L${shell pwd}/libpam_misc
+NEEDSONAME := no
+LDCONFIG := /sbin/ldconfig
+FAKEROOT :=
+SUPLEMENTED := $(PREFIX)/sbin
+SECUREDIR := $(LIBDIR)/security
+INCLUDED := /usr/include/security
+CONFIGED := /etc
+SCONFIGED := /etc/security
+EXTRALS := -lnsl -lcrypt
+WARNINGS := -Wall
diff --git a/contrib/libpam/defs/linux.defs b/contrib/libpam/defs/linux.defs
index 94e9968c6b25..0e2743203cd5 100644
--- a/contrib/libpam/defs/linux.defs
+++ b/contrib/libpam/defs/linux.defs
@@ -6,7 +6,7 @@
# preferred OS/vendor.
OS=linux
-ARCH=`uname -m | sed 's/^i?86/i386/'`
+ARCH=i386 # should be changed for alpha
CC=gcc
INSTALL=install
MKDIR=mkdir -p
@@ -16,6 +16,7 @@ LD=ld
LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
+LINKLIBS=-lc
SOSWITCH=-soname
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
@@ -29,4 +30,3 @@ SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security
-NSLLIB=-lnsl
diff --git a/contrib/libpam/defs/morgan.defs b/contrib/libpam/defs/morgan.defs
index 178de28d21a8..2b0cf289e46a 100644
--- a/contrib/libpam/defs/morgan.defs
+++ b/contrib/libpam/defs/morgan.defs
@@ -21,6 +21,7 @@ LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
SOSWITCH=-soname
+LINKLIBS=-lc
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
AR=ar -cr
diff --git a/contrib/libpam/defs/redhat.defs b/contrib/libpam/defs/redhat.defs
index 8c7e1e17f75a..a6ed36da1b20 100644
--- a/contrib/libpam/defs/redhat.defs
+++ b/contrib/libpam/defs/redhat.defs
@@ -9,7 +9,7 @@
# This file is the version used for Red Hat Linux.
OS=linux
-ARCH=$(shell rpm --showrc | grep 'build arch' | sed 's/^.*: //g')
+ARCH=$(shell rpm --showrc | grep '^build arch' | sed 's/^.*: //g')
CC=gcc
INSTALL=install
MKDIR=mkdir -p
@@ -20,6 +20,7 @@ LD_D=gcc -shared -Xlinker -x
LD_L=$(LD) -x -shared
USESONAME=yes
SOSWITCH=-soname
+LINKLIBS=-lc
NEEDSONAME=no
LDCONFIG=/sbin/ldconfig
AR=ar -cr
@@ -32,3 +33,4 @@ SECUREDIR=$(LIBDIR)/security
INCLUDED=/usr/include/security
CONFIGED=/etc
SCONFIGED=/etc/security
+EXTRALS=-lcrypt
diff --git a/contrib/libpam/defs/redhat4.defs b/contrib/libpam/defs/redhat4.defs
new file mode 100644
index 000000000000..219abeb6fd1d
--- /dev/null
+++ b/contrib/libpam/defs/redhat4.defs
@@ -0,0 +1,35 @@
+##
+# defs for Red Hat Linux
+# Michael K. Johnson <johnsonm@redhat.com>
+##
+# this file indicates the compiler and the various hardware/OS dependent
+# flags for installation. It also defines the various destinations of
+# installed files on the system.
+#
+# This file is the version used for Red Hat Linux.
+
+OS=linux
+ARCH=$(shell rpm --showrc | grep '^build arch' | sed 's/^.*: //g')
+CC=gcc
+INSTALL=install
+MKDIR=mkdir -p
+CFLAGS=$(RPM_OPT_FLAGS) -pipe -g
+ULIBS=#-lefence
+LD=ld
+LD_D=gcc -shared -Xlinker -x
+LD_L=$(LD) -x -shared
+USESONAME=yes
+SOSWITCH=-soname
+LINKLIBS=-lc
+NEEDSONAME=no
+LDCONFIG=/sbin/ldconfig
+AR=ar -cr
+RANLIB=ranlib
+FAKEROOT=$(RPM_BUILD_ROOT)
+PREFIX=
+SUPLEMENTED=$(PREFIX)/sbin
+LIBDIR=$(PREFIX)/lib
+SECUREDIR=$(LIBDIR)/security
+INCLUDED=/usr/include/security
+CONFIGED=/etc
+SCONFIGED=/etc/security
diff --git a/contrib/libpam/defs/solaris-2.1.5.defs b/contrib/libpam/defs/solaris-2.1.5.defs
new file mode 100644
index 000000000000..4624b604b7fa
--- /dev/null
+++ b/contrib/libpam/defs/solaris-2.1.5.defs
@@ -0,0 +1,45 @@
+##
+# Solaris defs contributed by Josh Wilmes <josh@makita.jpl.nasa.gov>
+##
+# this file indicates the compiler and the various hardware/OS dependent
+# flags for installation. It also defines the various destinations of
+# installed files on the system.
+#
+# This file is the default version. Please look in .../defs/ for your
+# preferred OS/vendor.
+
+# Please note that the linker used must be the GNU ld, not the native Sun
+# linker. It is fairly common for the gnu linker (/usr/ccs/bin/ld) to be
+# configured as the default linker for gcc. To tell gcc to use the
+# gnu linker, you need to set the GCC_EXEC_PREFIX environment variable
+# to point at the directory where the gnu linker is installed. Here's
+# what I do:
+# $ mkdir /tmp/foo
+# $ ln -s /path/to/gnu/ld /tmp/foo/ld
+# $ export GCC_EXEC_PREFIX=/tmp/foo/
+# $ export PATH=/tmp/foo:$PATH
+
+OS=solaris
+ARCH=sun
+CC=gcc
+INSTALL=install
+MKDIR=mkdir -p
+CFLAGS=-O7 -pipe -g -D__EXTENSIONS__ -Dsolaris
+ULIBS=
+LD_D=gcc -shared -Xlinker -x
+LD=ld
+LD_L=$(LD) -G
+USESONAME=yes
+SOSWITCH=-h
+NEEDSONAME=no
+LDCONFIG=/sbin/echo
+AR=ar -cr
+RANLIB=ranlib
+FAKEROOT=
+PREFIX=/usr
+SUPLEMENTED=$(PREFIX)/sbin
+LIBDIR=$(PREFIX)/lib
+SECUREDIR=$(LIBDIR)/security
+INCLUDED=/usr/include/security
+CONFIGED=/etc
+SCONFIGED=/etc/security
diff --git a/contrib/libpam/defs/suse.defs b/contrib/libpam/defs/suse.defs
new file mode 100644
index 000000000000..1fc6b7419427
--- /dev/null
+++ b/contrib/libpam/defs/suse.defs
@@ -0,0 +1,36 @@
+##
+# defs for SuSE Linux
+# Thorsten Kukuk <kukuk@suse.de>
+##
+# this file indicates the compiler and the various hardware/OS dependent
+# flags for installation. It also defines the various destinations of
+# installed files on the system.
+#
+# This file is the version used for SuSE Linux.
+
+OS=linux
+ARCH=$(shell rpm --showrc | grep 'build arch' | grep -v "compatible" | sed 's/^.*: //g')
+CC=gcc
+INSTALL=install
+MKDIR=mkdir -p
+CFLAGS=$(RPM_OPT_FLAGS) -pipe -D_REENTRANT
+ULIBS=#-lefence
+LD=ld
+LD_D=gcc -shared -Xlinker -x
+LD_L=$(LD) -x -shared
+USESONAME=yes
+SOSWITCH=-soname
+LINKLIBS=-lc
+NEEDSONAME=yes
+LDCONFIG=/sbin/ldconfig
+AR=ar -cr
+RANLIB=ranlib
+FAKEROOT=$(RPM_BUILD_ROOT)
+PREFIX=
+SUPLEMENTED=$(PREFIX)/sbin
+LIBDIR=$(PREFIX)/lib
+SECUREDIR=$(LIBDIR)/security
+INCLUDED=/usr/include/security
+CONFIGED=/etc
+SCONFIGED=/etc/security
+EXTRALS=-lcrypt
diff --git a/contrib/libpam/doc/CREDITS b/contrib/libpam/doc/CREDITS
index 95ca2ab36e02..528032bbb8ae 100644
--- a/contrib/libpam/doc/CREDITS
+++ b/contrib/libpam/doc/CREDITS
@@ -1,29 +1,41 @@
<!--
an sgml list of people to credit for their contributions to Linux-PAM
- $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
+ $Id: CREDITS,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
-->
+Chris Adams,
Peter Allgeyer,
Tim Baverstock,
+Tim Berger,
Craig S. Bell,
Derrick J. Brashear,
Ben Buxton,
+Seth Chaiklin,
Oliver Crow,
Chris Dent,
Marc Ewing,
Cristian Gafton,
+Emmanuel Galanos,
+Brad M. Garcia,
Eric Hester,
+Michel D'Hooge,
Roger Hu,
Eric Jacksch,
Michael K. Johnson,
David Kinchlea,
+Olaf Kirch,
+Marcin Korzonek,
+Stephen Langasek,
Nicolai Langfeldt,
Elliot Lee,
+Luke Kenneth Casson Leighton,
Al Longyear,
Ingo Luetkebohle,
Marek Michalkiewicz,
+Robert Milkowski,
Aleph One,
Martin Pool,
Sean Reifschneider,
+Jan Rekorajski,
Erik Troan,
Theodore Ts'o,
Jeff Uphoff,
diff --git a/contrib/libpam/doc/Makefile b/contrib/libpam/doc/Makefile
index 866b408512df..8ff16077a82a 100644
--- a/contrib/libpam/doc/Makefile
+++ b/contrib/libpam/doc/Makefile
@@ -1,10 +1,13 @@
-### $Id: Makefile,v 1.9 1997/01/04 21:55:52 morgan Exp $
+### $Id: Makefile,v 1.3 2001/01/22 08:03:01 agmorgan Exp $
-TXTER=sgml2txt
-HTMLER=sgml2html
-# older distributions use, sgml2ps
-PSER=sgml2latex -p
+include ../Make.Rules
+
+# These two should probably be moved into autoconf...
+DOCDIR=/usr/doc/Linux-PAM
+MANDIR=/usr/man
+
+#######################################################
FILES=pam pam_appl pam_modules
FSRCS=pam.sgml pam_appl.sgml pam_modules.sgml
@@ -26,36 +29,48 @@ all: htmls texts postscript
htmls: $(HTMLS)
$(HTMLS) : $(FSRCS)
+ifeq ($(HAVE_SGML2HTML),yes)
@for i in $(FILES) ; do \
if [ ! -f "html/$$i.html" ] || [ "$$i.sgml" -nt "html/$$i.html" ]; \
then \
- cd html ; $(HTMLER) ../$$i ; \
+ cd html ; sgml2html ../$$i ; \
if [ $$? -ne 0 ]; then exit 1 ; fi ; \
cd .. ; \
fi ; \
done
+else
+ @echo XXX - you do not have the sgml2html binary installed
+endif
texts: $(TEXTS)
$(TEXTS) : $(FSRCS)
+ifeq ($(HAVE_SGML2TXT),yes)
@for i in $(FILES) ; do \
if [ ! -f "txts/$$i.txt" ] \
|| [ "$$i.sgml" -nt "txts/$$i.txt" ]; then \
- cd txts ; $(TXTER) ../$$i ; cd .. ; \
+ cd txts ; sgml2txt ../$$i ; cd .. ; \
fi ; \
done
+else
+ @echo XXX - you do not have the sgml2txt binary installed
+endif
postscript: $(PSFILES)
$(PSFILES): $(FSRCS)
+ifneq ($(PSER),)
@for i in $(FILES) ; do \
if [ ! -f "ps/$$i.ps" ] || [ "$$i.sgml" -nt "ps/$$i.ps" ]; then \
cd ps ; $(PSER) ../$$i ; cd .. ; \
fi ; \
done
+else
+ @echo XXX - neither sgml2ps nor sgml2latex binaries are installed
+endif
-pam.sgml: pam_source.sgml MODULES-SGML
- @sed -e '/^<!\-\- insert\-file MODULES\-SGML \-\->/r MODULES-SGML' pam_source.sgml > pam.sgml
+pam.sgml: pam_source.sgml MODULES-SGML CREDITS
+ @sed -e '/^<!\-\- insert\-file MODULES\-SGML \-\->/r MODULES-SGML' pam_source.sgml | sed -e '/^<!\-\- insert\-file CREDITS \-\->/r CREDITS' > pam.sgml
MODULES-SGML: $(MODULES)
@echo 'Building module text from files in modules/*.sgml'
@@ -67,11 +82,64 @@ MODULES-SGML: $(MODULES)
extraclean: clean
+remove:
+ cd man && for file in *.3 ; do \
+ rm -f $(FAKEROOT)$(MANDIR)/man3/$$file ; \
+ done
+ cd man && for file in *.8 ; do \
+ rm -f $(FAKEROOT)$(MANDIR)/man8/$$file ; \
+ done
+ cd txts && for file in *.txt; do \
+ rm -f $(FAKEROOT)$(DOCDIR)/text/$$file ; \
+ done
+ cd ps && for file in *.ps; do \
+ rm -f $(FAKEROOT)$(DOCDIR)/ps/$$file ; \
+ done
+ cd html && for file in *.html; do \
+ rm -f $(FAKEROOT)$(DOCDIR)/html/$$file ; \
+ done
+
+install: all
+ifeq ($(HAVE_SGML2TXT),yes)
+ mkdir -p $(FAKEROOT)$(DOCDIR)/text
+ for file in txts/*.txt; do \
+ install -m 644 $$file $(FAKEROOT)$(DOCDIR)/text ; \
+ done
+endif
+ifneq ($(PSER),)
+ mkdir -p $(FAKEROOT)$(DOCDIR)/ps
+ for file in ps/*.ps; do \
+ install -m 644 $$file $(FAKEROOT)$(DOCDIR)/ps ; \
+ done
+endif
+ifeq ($(HAVE_SGML2HTML),yes)
+ mkdir -p $(FAKEROOT)$(DOCDIR)/html
+ for file in html/*.html; do \
+ install -m 644 $$file $(FAKEROOT)$(DOCDIR)/html ; \
+ done
+endif
+ mkdir -p $(FAKEROOT)$(MANDIR)/man{3,8}
+ for file in man/*.3 ; do \
+ install -m 644 $$file $(FAKEROOT)$(MANDIR)/man3 ; \
+ done
+ for file in man/*.8 ; do \
+ install -m 644 $$file $(FAKEROOT)$(MANDIR)/man8 ; \
+ done
+
+spec:
+ cd specs/formatter && make
+ specs/formatter/padout < specs/draft-morgan-pam.raw > specs/draft-morgan-pam-current.txt
+
+releasedocs: all spec
+ tar zvfc Linux-PAM-$(MAJOR_REL).$(MINOR_REL)-docs.tar.gz --exclude CVS html ps txts specs/draft-morgan-pam-current.txt
+
clean:
rm -f *~ *.bak
rm -f html/pam*.html
rm -f man/*~
rm -f $(TEXTS)
- rm -f $(PSFILES)
+ rm -f $(PSFILES) ps/missfont.log
rm -f MODULES-SGML pam.sgml
+ rm -f specs/draft-morgan-pam-current.txt
+ make -C specs/formatter clean
diff --git a/contrib/libpam/doc/html/index.html b/contrib/libpam/doc/html/index.html
index 91f990fc01e0..5cb1e0f0ebb4 100644
--- a/contrib/libpam/doc/html/index.html
+++ b/contrib/libpam/doc/html/index.html
@@ -17,5 +17,5 @@ currently not complete. However, in order of decreasing length:
<hr>
<p>
-REVISION: <tt>$Id: index.html,v 1.4 1996/11/21 06:51:01 morgan Exp $</tt>
+REVISION: <tt>$Id: index.html,v 1.1.1.1 2000/06/20 22:10:56 agmorgan Exp $</tt>
</BODY>
diff --git a/contrib/libpam/doc/man/pam.8 b/contrib/libpam/doc/man/pam.8
index 75384416f2cf..b814cebe2ec2 100644
--- a/contrib/libpam/doc/man/pam.8
+++ b/contrib/libpam/doc/man/pam.8
@@ -1,7 +1,7 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam.8,v 1.2 1997/02/15 18:37:27 morgan Exp $
-.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@linux.kernel.org>
-.TH PAM 8 "1997 Feb 9" "Linux-PAM 0.56" "Linux-PAM Manual"
+.\" $Id: pam.8,v 1.2 2001/01/20 23:47:07 agmorgan Exp $
+.\" Copyright (c) Andrew G. Morgan 1996-7,2001 <morgan@kernel.org>
+.TH PAM 8 "2001 Jan 20" "Linux-PAM 0.74" "Linux-PAM Manual"
.SH NAME
Linux-PAM \- Pluggable Authentication Modules for Linux
@@ -197,7 +197,14 @@ The meaning of each of these tokens was explained above.
The third field,
.BR control ", "
indicates the behavior of the PAM-API should the module fail to
-succeed in its authentication task. Valid
+succeed in its authentication task. There are two types of syntax for
+this control field: the simple one has a single simple keyword; the
+more complicated one involves a square-bracketed selection of
+.B value=action
+pairs.
+
+.sp
+For the simple (historical) syntax valid
.BR control
values are:
.BR requisite
@@ -224,8 +231,97 @@ only module in the stack associated with this
.BR service "+" type "."
.sp
+For the more complicated syntax valid
+.B control
+values have the following form:
+.sp
+.RB [value1=action1 value2=action2 ...]
+.sp
+Where
+.B valueN
+corresponds to the return code from the function invoked in the module
+for which the line is defined. It is selected from one of these:
+.BR success ;
+.BR open_err ;
+.BR symbol_err ;
+.BR service_err ;
+.BR system_err ;
+.BR buf_err ;
+.BR perm_denied ;
+.BR auth_err ;
+.BR cred_insufficient ;
+.BR authinfo_unavail ;
+.BR user_unknown ;
+.BR maxtries ;
+.BR new_authtok_reqd ;
+.BR acct_expired ;
+.BR session_err ;
+.BR cred_unavail ;
+.BR cred_expired ;
+.BR cred_err ;
+.BR no_module_data ;
+.BR conv_err ;
+.BR authtok_err ;
+.BR authtok_recover_err ;
+.BR authtok_lock_busy ;
+.BR authtok_disable_aging ;
+.BR try_again ;
+.BR ignore ;
+.BR abort ;
+.BR authtok_expired ;
+.BR module_unknown ;
+.BR bad_item "; and"
+.BR default .
+The last of these,
+.BR default ,
+implies 'all
+.BR valueN 's
+not mentioned explicitly. Note, the full list of PAM errors is
+available in /usr/include/security/_pam_types.h . The
+.B actionN
+can be: an unsigned integer,
+.BR J ,
+signifying an action of 'jump over the next J modules in the stack';
+or take one of the following forms:
+.br
+.B ignore
+- when used with a stack of modules, the module's return status will
+not contribute to the return code the application obtains;
+.br
+.B bad
+- this action indicates that the return code should be thought of as
+indicative of the module failing. If this module is the first in the
+stack to fail, its status value will be used for that of the whole
+stack.
+.br
+.B die
+- equivalent to bad with the side effect of terminating the module
+stack and PAM immediately returning to the application.
+.br
+.B ok
+- this tells PAM that the administrator thinks this return code
+should contribute directly to the return code of the full stack of
+modules. In other words, if the former state of the stack would lead
+to a return of
+.BR PAM_SUCCESS ,
+the module's return code will override this value. Note, if the former
+state of the stack holds some value that is indicative of a modules
+failure, this 'ok' value will not be used to override that value.
+.br
+.B done
+- equivalent to ok with the side effect of terminating the module
+stack and PAM immediately returning to the application.
+.br
+.B reset
+- clear all memory of the state of the module stack and start again
+with the next stacked module.
+
+.sp
.BR module-path
-- this is the full filename of the PAM to be used by the application
+- this is either the full filename of the PAM to be used by the
+application (it begins with a '/'), or a relative pathname from the
+default module location:
+.BR /lib/security/ .
.sp
.BR module-arguments
@@ -238,19 +334,13 @@ documented for each individual module.
.br
.BR /etc/pam.d/ " - the"
.BR Linux-PAM
-configuration directory. If this directory is present, the
+configuration directory. Generally, if this directory is present, the
.B /etc/pam.conf
file is ignored.
.br
-.BR /usr/lib/libpam.so.X " - the dynamic library"
+.BR /lib/libpam.so.X " - the dynamic library"
.br
-.BR /usr/lib/security/*.so " - the PAMs
-
-.sp
-Note, to conform to the Linux File-system standard, the libraries and
-modules in your system may be located in
-.BR /lib " and " /lib/security
-respectively.
+.BR /lib/security/*.so " - the PAMs
.SH ERRORS
Typically errors generated by the
@@ -261,8 +351,8 @@ system of libraries, will be written to
.SH "CONFORMING TO"
DCE-RFC 86.0, October 1995.
.br
-Contains additional features, currently under consideration by the
-DCE-RFC committee.
+Contains additional features, but remains backwardly compatible with
+this RFC.
.SH BUGS
.sp 2
@@ -273,7 +363,7 @@ None known.
The three
.BR Linux-PAM
Guides, for
-.BR "System administrators" ", "
+.BR "system administrators" ", "
.BR "module developers" ", "
and
.BR "application developers" ". "
diff --git a/contrib/libpam/doc/man/pam.conf.8 b/contrib/libpam/doc/man/pam.conf.8
index ea2dd98bfc9f..d067b5596eab 100644
--- a/contrib/libpam/doc/man/pam.conf.8
+++ b/contrib/libpam/doc/man/pam.conf.8
@@ -1 +1 @@
-.so man8/pam.8
+.so pam.8
diff --git a/contrib/libpam/doc/man/pam.d.8 b/contrib/libpam/doc/man/pam.d.8
index ea2dd98bfc9f..d067b5596eab 100644
--- a/contrib/libpam/doc/man/pam.d.8
+++ b/contrib/libpam/doc/man/pam.d.8
@@ -1 +1 @@
-.so man8/pam.8
+.so pam.8
diff --git a/contrib/libpam/doc/man/pam_authenticate.3 b/contrib/libpam/doc/man/pam_authenticate.3
index f631c47286be..7383f5f06b40 100644
--- a/contrib/libpam/doc/man/pam_authenticate.3
+++ b/contrib/libpam/doc/man/pam_authenticate.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_authenticate.3,v 1.2 1997/02/15 18:39:59 morgan Exp $
+.\" $Id: pam_authenticate.3,v 1.1.1.1 2000/06/20 22:10:57 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
.TH PAM_AUTHENTICATE 3 "1996 Dec 9" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_chauthtok.3 b/contrib/libpam/doc/man/pam_chauthtok.3
index b0997d592893..a0466f0fccc6 100644
--- a/contrib/libpam/doc/man/pam_chauthtok.3
+++ b/contrib/libpam/doc/man/pam_chauthtok.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_chauthtok.3,v 1.2 1997/02/15 18:42:23 morgan Exp $
+.\" $Id: pam_chauthtok.3,v 1.1.1.1 2000/06/20 22:10:57 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_CHAUTHTOK 3 "1997 Jan 4" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_close_session.3 b/contrib/libpam/doc/man/pam_close_session.3
index c809a0e4f0d8..d851700cda02 100644
--- a/contrib/libpam/doc/man/pam_close_session.3
+++ b/contrib/libpam/doc/man/pam_close_session.3
@@ -1 +1 @@
-.so man3/pam_open_session.3
+.so pam_open_session.3
diff --git a/contrib/libpam/doc/man/pam_end.3 b/contrib/libpam/doc/man/pam_end.3
index 06fdabb9c462..de999f240cfb 100644
--- a/contrib/libpam/doc/man/pam_end.3
+++ b/contrib/libpam/doc/man/pam_end.3
@@ -1 +1 @@
-.so man3/pam_start.3
+.so pam_start.3
diff --git a/contrib/libpam/doc/man/pam_fail_delay.3 b/contrib/libpam/doc/man/pam_fail_delay.3
index 42bccd6b9258..3b72f3d98b42 100644
--- a/contrib/libpam/doc/man/pam_fail_delay.3
+++ b/contrib/libpam/doc/man/pam_fail_delay.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_fail_delay.3,v 1.2 1997/02/15 18:47:46 morgan Exp morgan $
+.\" $Id: pam_fail_delay.3,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_FAIL_DELAY 3 "1997 Jan 12" "Linux-PAM 0.56" "Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_open_session.3 b/contrib/libpam/doc/man/pam_open_session.3
index 1b2dcf980bdb..53f6adf12c75 100644
--- a/contrib/libpam/doc/man/pam_open_session.3
+++ b/contrib/libpam/doc/man/pam_open_session.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_open_session.3,v 1.2 1997/02/15 18:49:02 morgan Exp $
+.\" $Id: pam_open_session.3,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_OPEN_SESSION 3 "1997 Jan 4" "Linux-PAM 0.55" "App. Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_setcred.3 b/contrib/libpam/doc/man/pam_setcred.3
index 388a5d766703..ea251405ac7d 100644
--- a/contrib/libpam/doc/man/pam_setcred.3
+++ b/contrib/libpam/doc/man/pam_setcred.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_setcred.3,v 1.2 1997/02/15 18:50:49 morgan Exp morgan $
+.\" $Id: pam_setcred.3,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996,1997 <morgan@parc.power.net>
.TH PAM_SETCRED 3 "1997 July 6" "Linux-PAM 0.58" "App. Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_start.3 b/contrib/libpam/doc/man/pam_start.3
index 0299533b4f5e..a912cc754664 100644
--- a/contrib/libpam/doc/man/pam_start.3
+++ b/contrib/libpam/doc/man/pam_start.3
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: pam_start.3,v 1.2 1997/02/15 18:51:54 morgan Exp $
+.\" $Id: pam_start.3,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
.TH PAM_START 3 "1997 Feb 15" "Linux-PAM 0.56" "Application Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/man/pam_strerror.3 b/contrib/libpam/doc/man/pam_strerror.3
index 33b4fda4c31e..b2318f2884c7 100644
--- a/contrib/libpam/doc/man/pam_strerror.3
+++ b/contrib/libpam/doc/man/pam_strerror.3
@@ -1,8 +1,8 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
.\" ripped off from Rick Faith's getgroups man page
-.\" $Id: pam_strerror.3,v 1.2 1997/02/15 18:53:04 morgan Exp $
-.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@parc.power.net>
-.TH PAM_STRERROR 3 "1997 Feb 15" "Linux-PAM 0.56" "Programmers' Manual"
+.\" $Id: pam_strerror.3,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
+.\" Copyright (c) Andrew G. Morgan 1996-7 <morgan@linux.kernel.org>
+.TH PAM_STRERROR 3 "1999 Oct 4" "Linux-PAM 0.70" "Programmers' Manual"
.SH NAME
pam_strerror \- return a textual description of a Linux-PAM error
@@ -14,14 +14,16 @@ or,
.br
.B #include <security/pam_modules.h>
.sp
-.BI "const char *pam_strerror(" int " pam_error);
+.BI "const char * pam_strerror( pam_handle_t " "*pamh" ", int " pam_error ");"
.sp 2
.SH DESCRIPTION
.B pam_strerror
-This function returns a pointer to a line of text describing the
+This function returns some text describing the
.BR Linux-PAM
-error passed as its sole argument.
+error associated with the
+.B pam_error
+argument.
.SH "RETURN VALUE"
diff --git a/contrib/libpam/doc/man/template-man b/contrib/libpam/doc/man/template-man
index a635c8bd8024..11e7a061504a 100644
--- a/contrib/libpam/doc/man/template-man
+++ b/contrib/libpam/doc/man/template-man
@@ -1,5 +1,5 @@
.\" Hey Emacs! This file is -*- nroff -*- source.
-.\" $Id: template-man,v 1.1 1997/01/04 18:25:13 morgan Exp $
+.\" $Id: template-man,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
.\" Copyright (c) Andrew G. Morgan 1997 <morgan@parc.power.net>
.TH PAM_???? 2 "1997 Jan 4" "Linux-PAM 0.55" "Application Programmers' Manual"
.SH NAME
diff --git a/contrib/libpam/doc/modules/README b/contrib/libpam/doc/modules/README
index b97b2cd501b9..b6587f508c25 100644
--- a/contrib/libpam/doc/modules/README
+++ b/contrib/libpam/doc/modules/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.2 1996/11/17 17:20:28 morgan Exp $
+$Id: README,v 1.1.1.1 2000/06/20 22:10:58 agmorgan Exp $
This directory contains a number of sgml sub-files. One for each
documented module. They contain a description of each module and give
diff --git a/contrib/libpam/doc/modules/module.sgml-template b/contrib/libpam/doc/modules/module.sgml-template
index 53cd809f338d..3fffc754b047 100644
--- a/contrib/libpam/doc/modules/module.sgml-template
+++ b/contrib/libpam/doc/modules/module.sgml-template
@@ -1,9 +1,9 @@
<!--
- $Id: module.sgml-template,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: module.sgml-template,v 1.2 2001/02/11 07:52:56 agmorgan Exp $
This template file was written by Andrew G. Morgan
- <morgan@parc.power.net>
+ <morgan@kernel.org>
[
Text that should be deleted/replaced, is enclosed within
diff --git a/contrib/libpam/doc/modules/pam_access.sgml b/contrib/libpam/doc/modules/pam_access.sgml
new file mode 100644
index 000000000000..00c7ea169d00
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_access.sgml
@@ -0,0 +1,108 @@
+<!--
+
+ pam_access module docs added by Tim Berger <timb@transmeta.com>
+
+-->
+
+<sect1> The access module
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+
+<tt>pam_access</tt>
+
+
+<tag><bf>Author[s]:</bf></tag>
+
+Alexei Nogin &lt;alexei@nogin.dnttm.ru&gt;
+
+<tag><bf>Maintainer:</bf></tag>
+
+Author
+
+<tag><bf>Management groups provided:</bf></tag>
+
+account
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+Requires a configuration file. By default
+<tt>/etc/security/access.conf</tt> is used but this can be overridden.
+
+<tag><bf>Network aware:</bf></tag>
+
+Through <tt/PAM_TTY/ if set, otherwise attempts getting tty name of
+the stdin file descriptor with <tt/ttyname()/. Standard
+gethostname(), <tt/yp_get_default_domain()/, <tt/gethostbyname()/
+calls. <bf/NIS/ is used for netgroup support.
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+Provides logdaemon style login access control.
+
+<sect2> Account component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+
+<tt>accessfile=<it>/path/to/file.conf</it></tt>
+
+<tag><bf>Description:</bf></tag>
+
+This module provides logdaemon style login access control based on
+login names and on host (or domain) names, internet addresses (or
+network numbers), or on terminal line names in case of non-networked
+logins. Diagnostics are reported through <tt/syslog(3)/. Wietse
+Venema's <tt/login_access.c/ from <em/logdaemon-5.6/ is used with
+several changes by A. Nogin.
+
+<p>
+The behavior of this module can be modified with the following
+arguments:
+<itemize>
+
+<item><tt>accessfile=/path/to/file.conf</tt> -
+indicate an alternative <em/access/ configuration file to override
+the default. This can be useful when different services need different
+access lists.
+
+</itemize>
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+Use of module is recommended, for example, on administrative machines
+such as <bf/NIS/ servers and mail servers where you need several accounts
+active but don't want them all to have login capability.
+
+For <tt>/etc/pam.d</tt> style configurations where your modules live
+in <tt>/lib/security</tt>, start by adding the following line to
+<tt>/etc/pam.d/login</tt>, <tt>/etc/pam.d/rlogin</tt>,
+<tt>/etc/pam.d/rsh</tt> and <tt>/etc/pam.d/ftp</tt>:
+
+<tscreen>
+<verb>
+account required /lib/security/pam_access.so
+</verb>
+</tscreen>
+
+Note that use of this module is not effective unless your system ignores
+<tt>.rhosts</tt> files. See the the pam_rhosts_auth documentation.
+
+A sample <tt>access.conf</tt> configuration file is included with the
+distribution.
+
+</descrip>
diff --git a/contrib/libpam/doc/modules/pam_chroot.sgml b/contrib/libpam/doc/modules/pam_chroot.sgml
index 7f8c4a39b642..2366880eabfc 100644
--- a/contrib/libpam/doc/modules/pam_chroot.sgml
+++ b/contrib/libpam/doc/modules/pam_chroot.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_chroot.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: pam_chroot.sgml,v 1.1.1.1 2000/06/20 22:10:59 agmorgan Exp $
This file was written by Bruce Campbell <brucec@humbug.org.au>
-->
diff --git a/contrib/libpam/doc/modules/pam_cracklib.sgml b/contrib/libpam/doc/modules/pam_cracklib.sgml
index 4700c2a04f03..810b261e83e9 100644
--- a/contrib/libpam/doc/modules/pam_cracklib.sgml
+++ b/contrib/libpam/doc/modules/pam_cracklib.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_cracklib.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp morgan $
+ $Id: pam_cracklib.sgml,v 1.3 2000/12/04 15:23:15 baggins Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
long password amendments are from Philip W. Dalrymple III <pwd@mdtsoft.com>
@@ -48,10 +48,6 @@ Requires the system library <tt/libcrack/ and a system dictionary:
<p>
This module can be plugged into the <tt/password/ stack of a given
application to provide some plug-in strength-checking for passwords.
-(XXX - note this does not necessarily work with the pam_unix module,
-although it is known to work with the pam_pwdb replacement for the
-unix module -- see example and pam_pwdb write up for more
-information).
<p>
This module works in the following manner: it first calls the
@@ -70,23 +66,35 @@ Is the new password the the old one with only a change of case?
<item> <bf/Similar/ -
-Is the new password too much like the old one? This is controlled
-by one argument, <tt/difok/ which is a number of characters that if
-different between the old and new are enough to accept the new
+Is the new password too much like the old one? This is primarily
+controlled by one argument, <tt/difok/ which is a number of characters
+that if different between the old and new are enough to accept the new
password, this defaults to 10 or 1/2 the size of the new password
whichever is smaller.
-<item <bf/Simple/ -
+To avoid the lockup associated with trying to change a long and
+complicated password, <tt/difignore/ is available. This argument can
+be used to specify the minimum length a new password needs to be
+before the <tt/difok/ value is ignored. The default value for
+<tt/difignore/ is 23.
+
+
+<item> <bf/Simple/ -
Is the new password too small? This is controlled by 5 arguments
<tt/minlen/, <tt/dcredit/, <tt/ucredit/, <tt/lcredit/, and
<tt/ocredit/. See the section on the arguments for the details of how
these work and there defaults.
-<item <bf/Rotated/ -
+<item> <bf/Rotated/ -
Is the new password a rotated version of the old password?
+<item> <bf/Already used/ -
+
+Was the password used in the past? Previously used passwords are to
+be found in /etc/security/opasswd.
+
</itemize>
<p>
@@ -113,6 +121,7 @@ share most of these characters with the old password.
<tt/debug/; <tt/type=XXX/; <tt/retry=N/; <tt/difok=N/; <tt/minlen=N/;
<tt/dcredit=N/; <tt/ucredit=N/; <tt/lcredit=N/; <tt/ocredit=N/;
+<tt/use_authtok/;
<tag><bf>Description:</bf></tag>
@@ -204,14 +213,16 @@ character will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/ocredit/ is 1 which is the recommended value for
<tt/minlen/ less than 10.
+<item> <tt/use_authtok/ -
+
+This argument is used to <em/force/ the module to not prompt the user
+for a new password but use the one provided by the previously stacked
+<tt/password/ module.
+
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
-(At the time of writing, this module can only be stacked before the
-<tt/pam_pwdb/ module. Cracklib strength checking may be compiled by
-default into the <tt/pam_unix/ module.)
-
<p>
For an example of the use of this module, we show how it may be
stacked with the password component of <tt/pam_pwdb/:
diff --git a/contrib/libpam/doc/modules/pam_deny.sgml b/contrib/libpam/doc/modules/pam_deny.sgml
index 99f367156fe5..9fd0ea4358cd 100644
--- a/contrib/libpam/doc/modules/pam_deny.sgml
+++ b/contrib/libpam/doc/modules/pam_deny.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_deny.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp morgan $
+ $Id: pam_deny.sgml,v 1.1.1.1 2000/06/20 22:11:00 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
diff --git a/contrib/libpam/doc/modules/pam_env.sgml b/contrib/libpam/doc/modules/pam_env.sgml
index a62f4576f132..a6361cacc76a 100644
--- a/contrib/libpam/doc/modules/pam_env.sgml
+++ b/contrib/libpam/doc/modules/pam_env.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_env.sgml,v 1.1 1997/04/05 06:50:42 morgan Exp $
+ $Id: pam_env.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
This file was written by Dave Kinchlea <kinch@kinch.ark.com>
Ed. AGM
@@ -50,7 +50,8 @@ is the use of previously set environment variables as well as
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
-<tt/debug/; <tt/conffile=/<em/configuration-file-name/
+<tt/debug/; <tt/conffile=/<em/configuration-file-name/;
+<tt/envfile/=<em/env-file-name/; <tt/readenv/=<em/0|1/
<tag><bf>Description:</bf></tag>
This module allows you to (un)set arbitrary environment variables
@@ -60,9 +61,9 @@ and/or <em/PAM_ITEM/s.
<p>
All is controlled via a configuration file (by default,
<tt>/etc/security/pam_env.conf</tt> but can be overriden with
-<tt>connfile</tt> argument). Each line starts with the variable name,
+<tt>conffile</tt> argument). Each line starts with the variable name,
there are then two possible options for each variable <bf>DEFAULT</bf>
-and <bf>OVERRIDE</bf>. <bf>DEFAULT</bf> allows and administrator to
+and <bf>OVERRIDE</bf>. <bf>DEFAULT</bf> allows an administrator to
set the value of the variable to some default value, if none is
supplied then the empty string is assumed. The <bf>OVERRIDE</bf>
option tells pam_env that it should enter in its value (overriding the
@@ -88,6 +89,12 @@ space is needed <bf>the full value must be delimited by the quotes and
embedded or escaped quotes are not supported</bf>.
<p>
+This module can also parse a file with simple <tt>KEY=VAL</tt> pairs
+on seperate lines (<tt>/etc/environment</tt> by default). You can
+change the default file to parse, with the <em/envfile/ flag and turn
+it on or off by setting the <em/readenv/ flag to 1 or 0 respectively.
+
+<p>
The behavior of this module can be modified with one of the following
flags:
@@ -102,6 +109,15 @@ flags:
the configuration file. This option overrides the default. You must
supply a complete path + file name.
+<item><tt/envfile=/<em/filename/
+- by default the file <tt>/etc/environment</tt> is used to load KEY=VAL
+pairs directly into the env. This option overrides the default. You must
+supply a complete path + file name.
+
+<item><tt/readenv=/<em/0|1/
+- turns on or off the reading of the file specified by envfile (0 is off,
+1 is on). By default this option is on.
+
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
diff --git a/contrib/libpam/doc/modules/pam_filter.sgml b/contrib/libpam/doc/modules/pam_filter.sgml
index 99f06ef01b64..a339be4e0e37 100644
--- a/contrib/libpam/doc/modules/pam_filter.sgml
+++ b/contrib/libpam/doc/modules/pam_filter.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_filter.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_filter.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
@@ -100,8 +100,8 @@ the filter might expect.
<p>
Permitted values for <tt/X/ are <tt/1/ and <tt/2/. These indicate the
-precise time the that filter is to be run. To explain this concept it
-will be useful to have read the Linux-PAM Module developer's
+precise time that the filter is to be run. To understand this concept
+it will be useful to have read the Linux-PAM Module developer's
guide. Basically, for each management group there are up to two ways
of calling the module's functions.
diff --git a/contrib/libpam/doc/modules/pam_ftp.sgml b/contrib/libpam/doc/modules/pam_ftp.sgml
index ca2e065d0122..81a2868dfed0 100644
--- a/contrib/libpam/doc/modules/pam_ftp.sgml
+++ b/contrib/libpam/doc/modules/pam_ftp.sgml
@@ -1,7 +1,7 @@
<!--
- $Id: pam_ftp.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: pam_ftp.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
- This file was written by Andrew G. Morgan <morgan@parc.power.net>
+ This file was written by Andrew G. Morgan <morgan@linux.kernel.org>
-->
<sect1>Anonymous access module
@@ -15,7 +15,7 @@
<tt/pam_ftp.so/
<tag><bf>Author:</bf></tag>
-Andrew G. Morgan &lt;morgan@parc.power.net&gt;
+Andrew G. Morgan &lt;morgan@linux.kernel.org&gt;
<tag><bf>Maintainer:</bf></tag>
Author.
@@ -56,7 +56,7 @@ mode of access.
This module intercepts the user's name and password. If the name is
``<tt/ftp/'' or ``<tt/anonymous/'', the user's password is broken up
-at the `<tt/@/' delimiter into a <tt/PAM_RUSER/ and a <tt/PAM_RHOST/
+at the `<tt/&commat;/' delimiter into a <tt/PAM_RUSER/ and a <tt/PAM_RHOST/
part; these pam-items being set accordingly. The username is set to
``<tt/ftp/''. In this case the module succeeds. Alternatively, the
module sets the <tt/PAM_AUTHTOK/ item with the entered password and
diff --git a/contrib/libpam/doc/modules/pam_group.sgml b/contrib/libpam/doc/modules/pam_group.sgml
index 360edee06afb..517da4e9e2a7 100644
--- a/contrib/libpam/doc/modules/pam_group.sgml
+++ b/contrib/libpam/doc/modules/pam_group.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_group.sgml,v 1.2 1997/01/04 20:50:10 morgan Exp $
+ $Id: pam_group.sgml,v 1.1.1.1 2000/06/20 22:11:01 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
diff --git a/contrib/libpam/doc/modules/pam_issue.sgml b/contrib/libpam/doc/modules/pam_issue.sgml
new file mode 100644
index 000000000000..1f617e3b870e
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_issue.sgml
@@ -0,0 +1,120 @@
+<!--
+
+Ben Collins <bcollins@debian.org>
+
+-->
+
+<sect1>Add issue file to user prompt
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+<tt/pam_issue/
+
+<tag><bf>Author:</bf></tag>
+Ben Collins &lt;bcollins@debian.org&gt;
+
+<tag><bf>Maintainer:</bf></tag>
+Author
+
+<tag><bf>Management groups provided:</bf></tag>
+Authentication (pam_sm_authenticate)
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+This module prepends the issue file (<em>/etc/issue</em> by default) when
+prompting for a username.
+
+<sect2>Authentication component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/issue=issue-file-name/; <tt/noesc/;
+
+<tag><bf>Description:</bf></tag>
+This module allows you 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 &bsol;x format).
+<p>
+Recognized escapes:
+<itemize>
+
+<item><tt/d/
+- current date
+
+<item><tt/s/
+- operating system name
+
+<item><tt/l/
+- name of this tty
+
+<item><tt/m/
+- architecture of this system (i686, sparc, powerpc, ...)
+
+<item><tt/n/
+- hostname of this system
+
+<item><tt/o/
+- domainname of this system
+
+<item><tt/r/
+- release number of the operation system (eg. 2.2.12)
+
+<item><tt/t/
+- current time
+
+<item><tt/u/
+- number of users currently logged in
+
+<item><tt/U/
+- same as <tt/u/, except it is suffixed with "user" or "users" (eg. "1
+user" or "10 users"
+
+<item><tt/v/
+- version/build-date of the operating system (eg. "&num;3 Mon Aug 23 14:38:16
+EDT 1999" on Linux).
+
+</itemize>
+
+<p>
+The behavior of this module can be modified with one of the following
+flags:
+
+<p>
+<itemize>
+
+<item><tt/issue/
+- the file to output if not using the default
+
+<item><tt/noesc/
+- turns off escape code parsing
+
+</itemize>
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+login auth pam_issue.so issue=/etc/issue
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_krb4.sgml b/contrib/libpam/doc/modules/pam_krb4.sgml
index edb87d1a0584..51a46522890c 100644
--- a/contrib/libpam/doc/modules/pam_krb4.sgml
+++ b/contrib/libpam/doc/modules/pam_krb4.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_krb4.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: pam_krb4.sgml,v 1.1.1.1 2000/06/20 22:11:01 agmorgan Exp $
This file was written by Derrick J. Brashear <shadow@DEMENTIA.ORG>
-->
diff --git a/contrib/libpam/doc/modules/pam_lastlog.sgml b/contrib/libpam/doc/modules/pam_lastlog.sgml
index 8c0e662c3cf9..451bfaa2fda6 100644
--- a/contrib/libpam/doc/modules/pam_lastlog.sgml
+++ b/contrib/libpam/doc/modules/pam_lastlog.sgml
@@ -1,7 +1,7 @@
<!--
- $Id: pam_mail.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_lastlog.sgml,v 1.2 2001/02/17 01:55:38 agmorgan Exp $
- This file was written by Andrew G. Morgan <morgan@parc.power.net>
+ This file was written by Andrew G. Morgan <morgan@kernel.org>
-->
<sect1>The last login module
@@ -15,7 +15,7 @@
<tt/pam_lastlog/
<tag><bf>Author:</bf></tag>
-Andrew G. Morgan &lt;morgan@parc.power.net&gt;
+Andrew G. Morgan &lt;morgan@kernel.org&gt;
<tag><bf>Maintainer:</bf></tag>
Author
@@ -30,7 +30,7 @@ auth
<tag><bf>Clean code base:</bf></tag>
<tag><bf>System dependencies:</bf></tag>
-uses information contained in the <tt>/var/log/wtmp</tt> file.
+uses information contained in the <tt>/var/log/lastlog</tt> file.
<tag><bf>Network aware:</bf></tag>
@@ -39,14 +39,14 @@ uses information contained in the <tt>/var/log/wtmp</tt> file.
<sect2>Overview of module
<p>
-This session module maintains the <tt>/var/log/wtmp</tt> file. Adding
+This session module maintains the <tt>/var/log/lastlog</tt> file. Adding
an open entry when called via the <tt>pam_open_seesion()</tt> function
and completing it when <tt>pam_close_session()</tt> is called. This
module can also display a line of information about the last login of
the user. If an application already performs these tasks, it is not
necessary to use this module.
-<sect2>Authentication component
+<sect2>Session component
<p>
<descrip>
@@ -61,7 +61,7 @@ necessary to use this module.
This module can be used to provide a ``Last login on ...''
message. when the user logs into the system from what ever application
uses the PAM libraries. In addition, the module maintains the
-<tt>/var/log/wtmp</tt> file.
+<tt>/var/log/lastlog</tt> file.
<p>
The behavior of this module can be modified with one of the following
@@ -85,10 +85,10 @@ attempt.
<item><tt/silent/
- neglect to inform the user about any previous login: just update
-the <tt>/var/log/wtmp</tt> file.
+the <tt>/var/log/lastlog</tt> file.
<item><tt/never/
-- if the <tt>/var/log/wtmp</tt> file does not contain any old entries
+- if the <tt>/var/log/lastlog</tt> file does not contain any old entries
for the user, indicate that the user has never previously logged in
with a ``welcome..." message.
@@ -98,13 +98,13 @@ with a ``welcome..." message.
This module can be used to indicate that the user has new mail when
they <em/login/ to the system. Here is a sample entry for your
-<tt>/etc/pam.conf</tt> file:
+<tt>/etc/pam.d/XXX</tt> file:
<tscreen>
<verb>
#
-# do we have any mail?
+# When were we last here?
#
-login session optional pam_lastlog.so
+session optional pam_lastlog.so
</verb>
</tscreen>
diff --git a/contrib/libpam/doc/modules/pam_limits.sgml b/contrib/libpam/doc/modules/pam_limits.sgml
index 6b98ea64fcbd..c4bdb4df503e 100644
--- a/contrib/libpam/doc/modules/pam_limits.sgml
+++ b/contrib/libpam/doc/modules/pam_limits.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_limits.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_limits.sgml,v 1.4 2001/03/29 04:21:16 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
from information compiled by Cristian Gafton (author of module)
@@ -74,6 +74,12 @@ verbose logging to <tt/syslog(3)/.
<item><tt>conf=/path/to/file.conf</tt> -
indicate an alternative <em/limits/ configuration file to the default.
+<item><tt/change_uid/ -
+change real uid to the user for who the limits are set up. Use this
+option if you have problems like login not forking a shell for user
+who has no processes. Be warned that something else may break when
+you do this.
+
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
@@ -103,7 +109,7 @@ The fields listed above should be filled as follows...<newline>
</itemize>
<p>
-<tt>&lt;type&gt;</tt> can have the two values:
+<tt>&lt;type&gt;</tt> can have the three values:
<itemize>
<item> <tt/hard/ for enforcing <em/hard/ resource limits. These limits
@@ -116,6 +122,9 @@ by any pre-exisiting <em/hard/ limits. The values specified with this
token can be thought of as <em/default/ values, for normal system
usage.
+<item> <tt/-/ for enforcing both <em/soft/ and <em/hard/ limits
+together.
+
</itemize>
<p>
@@ -132,15 +141,22 @@ usage.
<item><tt/nproc/ - max number of processes
<item><tt/as/ - address space limit
<item><tt/maxlogins/ - max number of logins for this user.
+<item><tt/priority/ - the priority to run user process with
</itemize>
<p>
-To completely disable limits for a user (or a group), a single dash
-(-) will do (Example: ``<tt/bin -/'', ``<tt/@admin -/''). Please
-remember that individual limits have priority over group limits, so if
-you impose no limits for <tt/admin/ group, but one of the members in this
-group have a limits line, the user will have its limits set according
-to this line.
+Note, if you specify a type of ``-'' but neglect to supply the
+<tt/item/ and <tt/value/ fields then the module will never enforce any
+limits on the corresponding user/group-members etc. . Note, the first
+entry of the form which applies to the authenticating user will
+override all other entries in the limits configuration file. In such
+cases, the <tt/pam_limits/ module will always return <tt/PAM_SUCCESS/.
+
+<p>
+In general, individual limits have priority over group limits, so if
+you impose no limits for <tt/admin/ group, but one of the members in
+this group have a limits line, the user will have its limits set
+according to this line.
<p>
Also, please note that all limit settings are set <em/per login/.
@@ -173,11 +189,11 @@ ftp hard nproc 0
</tscreen>
Note, the use of <tt/soft/ and <tt/hard/ limits for the same resource
(see <tt/@faculty/) -- this establishes the <em/default/ and permitted
-<em/extreme/ level of resources that the user can can obtain in a
-given service-session.
+<em/extreme/ level of resources that the user can obtain in a given
+service-session.
<p>
-For the services that need resources limits (login for example) put a
+For the services that need resources limits (login for example) put
the following line in <tt>/etc/pam.conf</tt> as the last line for that
service (usually after the pam_unix session line:
<tscreen>
diff --git a/contrib/libpam/doc/modules/pam_listfile.sgml b/contrib/libpam/doc/modules/pam_listfile.sgml
index fe4a0d27cc2e..1284d1b6ab75 100644
--- a/contrib/libpam/doc/modules/pam_listfile.sgml
+++ b/contrib/libpam/doc/modules/pam_listfile.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_listfile.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_listfile.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
@@ -111,8 +111,8 @@ Note, users listed in <tt>/etc/ftpusers</tt> file are
(counterintuitively) <bf/not/ allowed access to the ftp service.
<p>
-To allow login access only for certain users, you can use an
-pam.conf entry like this:
+To allow login access only for certain users, you can use a
+<tt/pam.conf/ entry like this:
<tscreen>
<verb>
#
diff --git a/contrib/libpam/doc/modules/pam_mail.sgml b/contrib/libpam/doc/modules/pam_mail.sgml
index 9a99f2064c36..65937a9f8dda 100644
--- a/contrib/libpam/doc/modules/pam_mail.sgml
+++ b/contrib/libpam/doc/modules/pam_mail.sgml
@@ -1,7 +1,7 @@
<!--
- $Id: pam_mail.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_mail.sgml,v 1.3 2001/03/19 01:46:41 agmorgan Exp $
- This file was written by Andrew G. Morgan <morgan@parc.power.net>
+ This file was written by Andrew G. Morgan <morgan@linux.kernel.org>
-->
<sect1>The mail module
@@ -15,13 +15,14 @@
<tt/pam_mail/
<tag><bf>Author:</bf></tag>
-Andrew G. Morgan &lt;morgan@parc.power.net&gt;
+Andrew G. Morgan &lt;morgan@linux.kernel.org&gt;
<tag><bf>Maintainer:</bf></tag>
Author
<tag><bf>Management groups provided:</bf></tag>
-auth
+Authentication (credential)
+Session (open)
<tag><bf>Cryptographically sensitive:</bf></tag>
@@ -42,14 +43,15 @@ Default mail directory <tt>/var/spool/mail/</tt>
This module looks at the user's mail directory and indicates
whether the user has any mail in it.
-<sect2>Authentication component
+<sect2>Session component
<p>
<descrip>
<tag><bf>Recognized arguments:</bf></tag>
-<tt/debug/; <tt/dir=/<em/direcory-name/; <tt/nopen/; <tt/close/;
-<tt/noenv/; <tt/empty/
+<tt/debug/; <tt/dir=/<em/directory-name/; <tt/nopen/; <tt/close/;
+<tt/noenv/; <tt/empty/; <tt/hash=/<em/hashcount/; <tt/standard/;
+<tt/quiet/;
<tag><bf>Description:</bf></tag>
@@ -60,12 +62,6 @@ user's mail folder. This module also sets the <bf/Linux-PAM/
environment variable, <tt/MAIL/, to the user's mail directory.
<p>
-Although the module supplies functions for the authentication
-management group of functions, it cannot be used to authenticate a
-user; its authentication function instructs <tt/libpam/ to simply
-ignore it when authenticating the user.
-
-<p>
The behavior of this module can be modified with one of the following
flags:
@@ -97,6 +93,17 @@ the user's credentials are revoked.
- indicate that the user's mail directory is empty if this is found to
be the case.
+<item><tt/hash=/<em/hashcount/
+- mail directory hash depth. For example, a <em/hashcount/ of 2 would
+make the mailfile be <tt>/var/spool/mail/u/s/user</tt>.
+
+<item><tt/standard/
+- old style "You have..." format which doesn't show the mail spool being used.
+ this also implies "empty"
+
+<item><tt/quiet/
+- only report when there is new mail.
+
</itemize>
<tag><bf>Examples/suggested usage:</bf></tag>
@@ -109,16 +116,27 @@ they <em/login/ to the system. Here is a sample entry for your
#
# do we have any mail?
#
-login auth optional pam_mail.so
+login session optional pam_mail.so
</verb>
</tscreen>
<p>
+Note, if the mail spool file (be it <tt>/var/spool/mail/$USER</tt> or
+a pathname given with the <tt>dir=</tt> parameter) is a directory then
+<tt>pam_mail</tt> assumes it is in the <it>Qmail Maildir</it> format.
+
+<p>
Note, some applications may perform this function themselves. In such
cases, this module is not necessary.
</descrip>
+<sect2>Authentication component
+
+<p>
+Then authentication companent works the same as the session component,
+except that everything is done during the <tt>pam_setcred()</tt> phase.
+
<!--
End of sgml insert for this module.
-->
diff --git a/contrib/libpam/doc/modules/pam_mkhomedir.sgml b/contrib/libpam/doc/modules/pam_mkhomedir.sgml
new file mode 100644
index 000000000000..075e16f9fc05
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_mkhomedir.sgml
@@ -0,0 +1,83 @@
+<!--
+
+Ben Collins <bcollins@debian.org>
+
+-->
+
+<sect1>Create home directories on initial login
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+<tt/pam_mkhomedir/
+
+<tag><bf>Author:</bf></tag>
+Jason Gunthorpe &lt;jgg@ualberta.ca&gt;
+
+<tag><bf>Maintainer:</bf></tag>
+Ben Collins &lt;bcollins@debian.org&gt;
+
+<tag><bf>Management groups provided:</bf></tag>
+Session
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+Creates home directories on the fly for authenticated users.
+
+<sect2>Session component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/; <tt/skel=skeleton-dir/; <tt/umask=octal-umask/;
+
+<tag><bf>Description:</bf></tag>
+This module is useful for distributed systems where the user account is
+managed in a central database (such as NIS, NIS+, or LDAP) and accessed
+through miltiple systems. It frees the administrator from having to create
+a default home directory on each of the systems by creating it upon the
+first succesfully authenticated login of that user. The skeleton directory
+(usually /etc/skel/) is used to copy default files and also set's a umask
+for the creation.
+
+<p>
+The behavior of this module can be modified with one of the following
+flags:
+
+<p>
+<itemize>
+
+<item><tt/skel/
+- The skeleton directory for default files to copy to the new home directory.
+
+<item><tt/umask/
+- An octal for of the same format as you would pass to the shells umask command.
+
+</itemize>
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_motd.sgml b/contrib/libpam/doc/modules/pam_motd.sgml
new file mode 100644
index 000000000000..8ddc63924e78
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_motd.sgml
@@ -0,0 +1,77 @@
+<!--
+
+Ben Collins <bcollins@debian.org>
+
+-->
+
+<sect1>Output the motd file
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+<tt/pam_motd/
+
+<tag><bf>Author:</bf></tag>
+Ben Collins &lt;bcollins@debian.org&gt;
+
+<tag><bf>Maintainer:</bf></tag>
+Author
+
+<tag><bf>Management groups provided:</bf></tag>
+Session (open)
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+This module outputs the motd file (<em>/etc/motd</em> by default) upon
+successful login.
+
+<sect2>Session component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/; <tt/motd=motd-file-name/;
+
+<tag><bf>Description:</bf></tag>
+This module allows you to have arbitrary motd's (message of the day)
+output after a succesful login. By default this file is <em>/etc/motd</em>,
+but is configurable to any file.
+
+<p>
+The behavior of this module can be modified with one of the following
+flags:
+
+<p>
+<itemize>
+
+<item><tt/motd/
+- the file to output if not using the default.
+
+</itemize>
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+login session pam_motd.so motd=/etc/motd
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_nologin.sgml b/contrib/libpam/doc/modules/pam_nologin.sgml
index de4b32a8efbd..963fa4282b4f 100644
--- a/contrib/libpam/doc/modules/pam_nologin.sgml
+++ b/contrib/libpam/doc/modules/pam_nologin.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_nologin.sgml,v 1.2 1997/01/04 21:56:55 morgan Exp $
+ $Id: pam_nologin.sgml,v 1.1.1.1 2000/06/20 22:11:02 agmorgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
diff --git a/contrib/libpam/doc/modules/pam_permit.sgml b/contrib/libpam/doc/modules/pam_permit.sgml
index 84df9fc1754f..2588110ddcd4 100644
--- a/contrib/libpam/doc/modules/pam_permit.sgml
+++ b/contrib/libpam/doc/modules/pam_permit.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_permit.sgml,v 1.2 1997/02/15 18:20:12 morgan Exp $
+ $Id: pam_permit.sgml,v 1.1.1.1 2000/06/20 22:11:02 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
diff --git a/contrib/libpam/doc/modules/pam_pwdb.sgml b/contrib/libpam/doc/modules/pam_pwdb.sgml
index c9f7bff1124a..625572064bb2 100644
--- a/contrib/libpam/doc/modules/pam_pwdb.sgml
+++ b/contrib/libpam/doc/modules/pam_pwdb.sgml
@@ -1,7 +1,7 @@
<!--
- $Id: pam_pwdb.sgml,v 1.3 1997/04/05 06:50:42 morgan Exp morgan $
+ $Id: pam_pwdb.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
- This file was written by Andrew G. Morgan <morgan@parc.power.net>
+ This file was written by Andrew G. Morgan <morgan@kernel.org>
-->
<sect1>The Password-Database module
@@ -16,7 +16,7 @@ pam_pwdb
<tag><bf>Author:</bf></tag>
Cristian Gafton &lt;gafton@redhat.com&gt; <newline>
-and Andrew G. Morgan &lt;morgan@parc.power.net&gt;
+and Andrew G. Morgan &lt;morgan@kernel.org&gt;
<tag><bf>Maintainer:</bf></tag>
Authors.
@@ -44,8 +44,8 @@ This module is a pluggable replacement for the <tt/pam_unix_../
modules. It uses the generic interface of the <em/Password Database/
library
<tt><htmlurl
-url="http://parc.power.net/morgan/libpwdb/index.html"
-name="http://parc.power.net/morgan/libpwdb/index.html"></tt>.
+url="http://linux.kernel.org/morgan/libpwdb/index.html"
+name="http://linux.kernel.org/morgan/libpwdb/index.html"></tt>.
<sect2>Account component
@@ -101,7 +101,8 @@ login account required pam_pwdb.so
<tt/use_first_pass/;
<tt/try_first_pass/;
<tt/nullok/;
-<tt/nodelay/
+<tt/nodelay/;
+<tt/likeauth/
<tag><bf>Description:</bf></tag>
@@ -141,6 +142,12 @@ it. It is called transparently on behalf of the user by the
authenticating component of this module. In this way it is possible
for applications like <em>xlock</em> to work without being setuid-root.
+<p>
+The <tt>likeauth</tt> argument makes the module return the same value
+when called as a credential setting module and an authentication
+module. This will help libpam take a sane path through the auth
+component of your configuration file.
+
<tag><bf>Examples/suggested usage:</bf></tag>
The correct functionality of this module is dictated by having an
diff --git a/contrib/libpam/doc/modules/pam_radius.sgml b/contrib/libpam/doc/modules/pam_radius.sgml
index 4d5f39ab3422..8ebfa0a83592 100644
--- a/contrib/libpam/doc/modules/pam_radius.sgml
+++ b/contrib/libpam/doc/modules/pam_radius.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_radius.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_radius.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
This file was written by Cristian Gafton <gafton@redhat.com>
-->
@@ -44,7 +44,7 @@ yes; this is a network module (independent of application).
<p>
This module is intended to provide the session service for users
-autheticated with a RADIUS server. At the present stage, the only
+authenticated with a RADIUS server. At the present stage, the only
option supported is the use of the RADIUS server as an accounting
server.
@@ -60,7 +60,7 @@ server.
<tag><bf>Description:</bf></tag>
This module is intended to provide the session service for users
-autheticated with a RADIUS server. At the present stage, the only
+authenticated with a RADIUS server. At the present stage, the only
option supported is the use of the RADIUS server as an <em/accounting/
server.
diff --git a/contrib/libpam/doc/modules/pam_rhosts.sgml b/contrib/libpam/doc/modules/pam_rhosts.sgml
index 91001022a2b0..520dd4271b88 100644
--- a/contrib/libpam/doc/modules/pam_rhosts.sgml
+++ b/contrib/libpam/doc/modules/pam_rhosts.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_rhosts.sgml,v 1.4 1997/04/05 06:50:42 morgan Exp $
+ $Id: pam_rhosts.sgml,v 1.1.1.1 2000/06/20 22:11:04 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
@@ -81,7 +81,8 @@ of independently probing the network connection for such information.
<p>
In the case of <tt/root/-access, the <tt>/etc/host.equiv</tt> file is
-<em/ignored/. Instead, the superuser must have a correctly configured
+<em/ignored/ unless the <tt>hosts_equiv_rootok</tt> option
+should be used. Instead, the superuser must have a correctly configured
personal configuration file.
<p>
@@ -103,6 +104,12 @@ fix this!)
ignore the contents of the <tt>/etc/hosts.equiv</tt> file.
<item>
+<tt/hosts_equiv_rootok/ -
+allow the use of <tt>/etc/hosts.equiv</tt> for superuser. Without this
+option <tt>/etc/hosts.equiv</tt> is not consulted for the superuser account.
+This option has no effect if the <tt>no_hosts_equiv</tt> option is used.
+
+<item>
<tt/no_rhosts/ -
ignore the contents of all user's personal configuration file
<tt>~/.rhosts</tt>.
diff --git a/contrib/libpam/doc/modules/pam_rootok.sgml b/contrib/libpam/doc/modules/pam_rootok.sgml
index ff6aa86e34da..f7a7259c7652 100644
--- a/contrib/libpam/doc/modules/pam_rootok.sgml
+++ b/contrib/libpam/doc/modules/pam_rootok.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_rootok.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_rootok.sgml,v 1.1.1.1 2000/06/20 22:11:04 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
diff --git a/contrib/libpam/doc/modules/pam_securetty.sgml b/contrib/libpam/doc/modules/pam_securetty.sgml
index 276ae90435c2..fc89af23460a 100644
--- a/contrib/libpam/doc/modules/pam_securetty.sgml
+++ b/contrib/libpam/doc/modules/pam_securetty.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_securetty.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: pam_securetty.sgml,v 1.1.1.1 2000/06/20 22:11:04 agmorgan Exp $
This file was written by Michael K. Johnson <johnsonm@redhat.com>
-->
diff --git a/contrib/libpam/doc/modules/pam_tally.sgml b/contrib/libpam/doc/modules/pam_tally.sgml
new file mode 100644
index 000000000000..aca41bbde0f0
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_tally.sgml
@@ -0,0 +1,191 @@
+<!--
+
+ $Id: pam_tally.sgml,v 1.1 2001/02/11 07:52:56 agmorgan Exp $
+
+ This template file was written by Andrew G. Morgan <morgan@kernel.org>
+ adapted from text provided by Tim Baverstock.
+-->
+
+<sect1>The login counter (tallying) module
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+pam_tally
+
+<tag><bf>Author[s]:</bf></tag>
+Tim Baverstock
+
+<tag><bf>Maintainer:</bf></tag>
+
+<tag><bf>Management groups provided:</bf></tag>
+auth; account
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+A faillog file (default location /var/log/faillog)
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+This module maintains a count of attempted accesses, can reset count
+on success, can deny access if too many attempts fail.
+
+<p>
+pam_tally comes in two parts: <tt>pam_tally.so</tt> and
+<tt>pam_tally</tt>. The former is the PAM module and the latter, a
+stand-alone program. <tt>pam_tally</tt> is an (optional) application
+which can be used to interrogate and manipulate the counter file. It
+can display users' counts, set individual counts, or clear all
+counts. Setting artificially high counts may be useful for blocking
+users without changing their passwords. For example, one might find it
+useful to clear all counts every midnight from a cron job.
+
+<p>
+The counts file is organized as a binary-word array, indexed by
+uid. You can probably make sense of it with <tt>od</tt>, if you don't
+want to use the supplied appliction.
+
+<p>
+Note, there are some outstanding issues with this module:
+<tt>pam_tally</tt> is very dependant on <tt>getpw*()</tt> - a database
+of usernames would be much more flexible; the `keep a count of current
+logins' bit has been <tt>#ifdef</tt>'d out and you can only reset the
+counter on successful authentication, for now.
+
+<sect3>Generic options accepted by both components
+<p>
+<itemize>
+<item> <tt>onerr=</tt>(<tt>succeed</tt>|<tt>fail</tt>):
+ if something weird happens, such as unable to open the file, how
+ should the module react?
+<item> <tt>file=</tt><em>/where/to/keep/counts</em>:
+ specify the file location for the counts.
+ The default location is <tt>/var/log/faillog</tt>.
+</itemize>
+
+<sect2>Authentication component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt>onerr=</tt>(<tt>succeed</tt>|<tt>fail</tt>);
+<tt>file=</tt>/where/to/keep/counts;
+<tt>no_magic_root</tt>
+
+<tag><bf>Description:</bf></tag>
+
+<p>
+The authentication component of this module increments the attempted
+login counter.
+
+<p>
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+<p>
+The module argument <tt>no_magic_root</tt> is used to indicate that if
+the module is invoked by a user with uid=0, then the counter is
+incremented. The sys-admin should use this for daemon-launched
+services, like <tt>telnet</tt>/<tt>rsh</tt>/<tt>login</tt>. For user
+launched services, like <tt>su</tt>, this argument should be omitted.
+
+<p>
+By way of more explanation, when a process already running as root
+tries to access some service, the access is <em>magic</em>, and
+bypasses <tt>pam_tally</tt>'s checks: this is handy for <tt>su</tt>ing
+from root into an account otherwise blocked. However, for services
+like <tt>telnet</tt> or <tt>login</tt>, which always effectively run
+from the root account, root (ie everyone) shouldn't be granted this
+magic status, and the flag `no_magic_root' should be set in this
+situation, as noted in the summary above.
+
+</descrip>
+
+<sect2>Account component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt>onerr=</tt>(<tt>succeed</tt>|<tt>fail</tt>);
+<tt>file=</tt>/where/to/keep/counts;
+<tt>deny=</tt><em>n</em>;
+<tt>no_magic_root</tt>;
+<tt>even_deny_root_account</tt>;
+<tt>reset</tt>;
+<tt>no_reset</tt>;
+<tt>per_user</tt>;
+<tt>no_lock_time</tt>
+
+<tag><bf>Description:</bf></tag>
+
+<p>
+The account component can deny access and/or reset the attempts
+counter. It also checks to make sure that the counts file is a plain
+file and not world writable.
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+<p>
+The <tt>deny=</tt><em>n</em> option is used to deny access if tally
+for this user exceeds <em>n</em>. The presence of
+<tt>deny=</tt><em>n</em> changes the default for
+<tt>reset</tt>/<tt>no_reset</tt> to <tt>reset</tt>, unless the user
+trying to gain access is root and the <tt>no_magic_root</tt> option
+has NOT been specified.
+
+<p>
+The <tt>no_magic_root</tt> option ensures that access attempts by root
+DON'T ignore deny. Use this for daemon-based stuff, like
+<tt>telnet</tt>/<tt>rsh</tt>/<tt>login</tt>.
+
+<p>
+The <tt>even_deny_root_account</tt> option is used to ensure that the
+root account can become unavailable. <bf>Note</bf> that magic root
+trying to gain root bypasses this, but normal users can be locked out.
+
+<p>
+The <tt>reset</tt> option instructs the module to reset count to 0 on
+successful entry, even for magic root. The <tt>no_reset</tt> option is
+used to instruct the module to not reset the count on successful
+entry. This is the default unless <tt>deny</tt> exists and the user
+attempting access is NOT magic root.
+
+<p>
+If <tt>/var/log/faillog</tt> contains a non-zero <tt>.fail_max</tt>
+field for this user then the <tt>per_user</tt> module argument will
+ensure that the module uses this value and not the global
+<tt>deny=</tt><em>n</em> parameter.
+
+<p>
+The <tt>no_lock_time</tt> option is for ensuring that the module does
+not use the <tt>.fail_locktime</tt> field in /var/log/faillog for this
+user.
+
+<p>
+Normally, failed attempts to access root will <bf>NOT</bf> 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
+<tt>su</tt> or at the machine console (not
+<tt>telnet</tt>/<tt>rsh</tt>, etc), this is safe. If you really want
+root to be blocked for some given service, use
+<tt>even_deny_root_account</tt>.
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_time.sgml b/contrib/libpam/doc/modules/pam_time.sgml
index 0b3cddfcb44a..8889c4501dea 100644
--- a/contrib/libpam/doc/modules/pam_time.sgml
+++ b/contrib/libpam/doc/modules/pam_time.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_time.sgml,v 1.2 1997/02/15 18:25:44 morgan Exp $
+ $Id: pam_time.sgml,v 1.2 2001/03/19 01:46:41 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
@@ -142,7 +142,7 @@ Some examples of rules that can be placed in the
<tt>/etc/security/time.conf</tt> configuration file are the following:
<descrip>
-<tag><tt>login ; tty* &amp ; !ttyp* ; !root ; !Al0000-2400</tt></tag>
+<tag><tt>login ; tty* &amp; !ttyp* ; !root ; !Al0000-2400</tt></tag>
all users except for <tt/root/ are denied access to console-login at
all times.
diff --git a/contrib/libpam/doc/modules/pam_unix.sgml b/contrib/libpam/doc/modules/pam_unix.sgml
new file mode 100644
index 000000000000..71cb07e32863
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_unix.sgml
@@ -0,0 +1,288 @@
+<!--
+ This file was written by Andrew G. Morgan <morgan@linux.kernel.org>
+
+ Converted from the pam_pwdb.sgml file for pam_unix by Ben Collins <bcollins@debian.org>
+-->
+
+<sect1>The Unix Password module
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+pam_unix
+
+<tag><bf>Author:</bf></tag>
+
+<tag><bf>Maintainer:</bf></tag>
+
+<tag><bf>Management groups provided:</bf></tag>
+account; authentication; password; session
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+This is the standard Unix authentication module. It uses standard calls
+from the system's libraries to retrieve and set account information as
+well as authentication. Usually this is obtained from the /etc/passwd
+and the /etc/shadow file as well if shadow is enabled.
+
+<sect2>Account component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/; <tt/audit/
+
+<tag><bf>Description:</bf></tag>
+
+The <tt/debug/ argument makes the accounting functions of this module
+<tt/syslog(3)/ more information on its actions. (Remaining arguments
+supported by the other functions of this module are silently ignored,
+but others are logged as errors through <tt/syslog(3)/). The <tt/audit/
+argument causes even more logging.
+
+Based on the following <tt/shadow/ elements:
+<tt/expire/;
+<tt/last_change/;
+<tt/max_change/;
+<tt/min_change/;
+<tt/warn_change/,
+this module performs the task of establishing the status of the user's
+account and password. In the case of the latter, it may offer advice
+to the user on changing their password or, through the
+<tt/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 <em/GNU Libc/ info documents. Should the user's record
+not contain one or more of these entries, the corresponding <em/shadow/
+check is not performed.
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+In its accounting mode, this module can be inserted as follows:
+<tscreen>
+<verb>
+#
+# Ensure users account and password are still active
+#
+login account required pam_unix.so
+</verb>
+</tscreen>
+
+</descrip>
+
+<sect2>Authentication component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/;
+<tt/audit/;
+<tt/use_first_pass/;
+<tt/try_first_pass/;
+<tt/nullok/;
+<tt/nodelay/
+
+<tag><bf>Description:</bf></tag>
+
+The <tt/debug/ argument makes the authentication functions of this
+module <tt/syslog(3)/ more information on its actions. The <tt/audit/
+causes even more information to be logged.
+
+<p>
+The default action of this module is to not permit the user access to
+a service if their <em/official/ password is blank. The <tt/nullok/
+argument overrides this default.
+
+<p>
+When given the argument <tt/try_first_pass/, before prompting the user
+for their password, the module first tries the previous stacked
+<tt/auth/-module's password in case that satisfies this module as
+well. The argument <tt/use_first_pass/ forces the module to use such a
+recalled password and will never prompt the user - if no password is
+available or the password is not appropriate, the user will be denied
+access.
+
+<p>
+The argument, <tt>nodelay</tt>, can be used to discourage the
+authentication component from requesting a delay should the
+authentication as a whole fail. The default action is for the module
+to request a delay-on-failure of the order of one second.
+
+<p>
+Remaining arguments, supported by the other functions of this module,
+are silently ignored. Other arguments are logged as errors through
+<tt/syslog(3)/.
+
+<p>
+A helper binary, <tt>unix_chkpwd</tt>, is provided to check the user's
+password when it is stored in a read protected database. This binary
+is very simple and will only check the password of the user invoking
+it. It is called transparently on behalf of the user by the
+authenticating component of this module. In this way it is possible
+for applications like <em>xlock</em> to work without being setuid-root.
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+The correct functionality of this module is dictated by having an
+appropriate <tt>/etc/nsswitch.conf</tt> file, the user
+databases specified there dictate the source of the authenticated
+user's record.
+<p>
+In its authentication mode, this module can be inserted as follows:
+<tscreen>
+<verb>
+#
+# Authenticate the user
+#
+login auth required pam_unix.so
+</verb>
+</tscreen>
+
+</descrip>
+
+<sect2>Password component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/;
+<tt/audit/;
+<tt/nullok/;
+<tt/not_set_pass/;
+<tt/use_authtok/;
+<tt/try_first_pass/;
+<tt/use_first_pass/;
+<tt/md5/;
+<tt/bigcrypt/;
+<tt/shadow/;
+<tt/nis/;
+<tt/remember/
+
+<tag><bf>Description:</bf></tag>
+
+This part of the <tt/pam_unix/ module performs the task of updating
+the user's password.
+
+<p>
+In the case of conventional unix databases (which store the password
+encrypted) the <tt/md5/ argument is used to do the encryption with the
+MD5 function as opposed to the <em/conventional/ <tt/crypt(3)/ call.
+As an alternative to this, the <tt/bigcrypt/ argument can be used to
+encrypt more than the first 8 characters of a password with DEC's
+(Digital Equipment Cooperation) `C2' extension to the standard UNIX
+<tt/crypt()/ algorithm.
+
+<p>
+The <tt/nullok/ argument is used to permit the changing of a password
+<em/from/ an empty one. Without this argument, empty passwords are
+treated as account-locking ones.
+
+<p>
+The argument <tt/use_first_pass/ is used to lock the choice of old and
+new passwords to that dictated by the previously stacked <tt/password/
+module. The <tt/try_first_pass/ argument is used to avoid the user
+having to re-enter an old password when <tt/pam_unix/ follows a module
+that possibly shared the user's old password - if this old password is
+not correct the user will be prompted for the correct one. The
+argument <tt/use_authtok/ is used to <em/force/ this module to set the
+new password to the one provided by the previously stacked
+<tt/password/ module (this is used in an example of the stacking of
+the <em/Cracklib/ module documented above).
+
+<p>
+The <tt/not_set_pass/ argument is used to inform the module that it is
+not to pay attention to/make available the old or new passwords from/to
+other (stacked) password modules.
+
+<p>
+The <tt/debug/ argument makes the password functions of this module
+<tt/syslog(3)/ more information on its actions. Other arguments may be
+logged as erroneous to <tt/syslog(3)/. The <tt/audit/ argument causes
+even more information to be logged.
+
+<p>
+With the <tt/nis/ argument, <tt/pam_unix/ will attempt to use NIS RPC
+for setting new passwords.
+
+<p>
+The <tt/remember/ argument takes one value. This is the number of most
+recent passwords to save for each user. These are saved in
+<tt>/etc/security/opasswd</tt> in order to force password change history
+and keep the user from alternating between the same password too frequently.
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+Standard usage:
+<tscreen>
+<verb>
+#
+# Change the users password
+#
+passwd password required pam_unix.so
+</verb>
+</tscreen>
+
+<p>
+An example of the stacking of this module with respect to the
+pluggable password checking module, <tt/pam_cracklib/:
+<tscreen>
+<verb>
+#
+# Change the users password
+#
+passwd password required pam_cracklib.so retry=3 minlen=6 difok=3
+passwd password required pam_unix.so use_authtok nullok md5
+</verb>
+</tscreen>
+
+</descrip>
+
+<sect2>Session component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+
+<tag><bf>Description:</bf></tag>
+
+No arguments are recognized by this module component. Its action is
+simply to log the username and the service-type to
+<tt/syslog(3)/. Messages are logged at the beginning and end of the
+user's session.
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+The use of the session modules is straightforward:
+<tscreen>
+<verb>
+#
+# session opening and closing
+#
+login session required pam_unix.so
+</verb>
+</tscreen>
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_userdb.sgml b/contrib/libpam/doc/modules/pam_userdb.sgml
new file mode 100644
index 000000000000..bdbf80b821d0
--- /dev/null
+++ b/contrib/libpam/doc/modules/pam_userdb.sgml
@@ -0,0 +1,112 @@
+<!--
+ This file was written by Cristian Gafton <gafton@redhat.com>
+-->
+
+<sect1>The userdb module
+
+<sect2>Synopsis
+
+<p>
+<descrip>
+
+<tag><bf>Module Name:</bf></tag>
+<tt/pam_userdb/
+
+<tag><bf>Author:</bf></tag>
+Cristian Gafton &lt;gafton@redhat.com&gt;
+
+<tag><bf>Maintainer:</bf></tag>
+Author.
+
+<tag><bf>Management groups provided:</bf></tag>
+authentication
+
+<tag><bf>Cryptographically sensitive:</bf></tag>
+
+<tag><bf>Security rating:</bf></tag>
+
+<tag><bf>Clean code base:</bf></tag>
+
+<tag><bf>System dependencies:</bf></tag>
+Requires Berkeley DB.
+
+<tag><bf>Network aware:</bf></tag>
+
+</descrip>
+
+<sect2>Overview of module
+
+<p>
+Look up users in a .db database and verify their password against
+what is contained in that database.
+
+<sect2>Authentication component
+
+<p>
+<descrip>
+
+<tag><bf>Recognized arguments:</bf></tag>
+<tt/debug/;
+<tt/icase/;
+<tt/dump/;
+<tt/db=XXXX/;
+
+<tag><bf>Description:</bf></tag>
+
+This module is used to verify a username/password pair against values stored in
+a Berkeley DB database. The database is indexed by the username, and the data
+fields corresponding to the username keys are the passwords, in unencrypted form,
+so caution must be exercised over the access rights to the DB database itself..
+
+The module will read the password from the user using the conversation mechanism. If
+you are using this module on top of another authetication module (like <tt/pam_pwdb/;)
+then you should tell that module to read the entered password from the PAM_AUTHTOK field, which is set by this module.
+
+<p>
+The action of the module may be modified from this default by one or
+more of the following flags in the <tt>/etc/pam.d/&lt;service&gt;</tt> file.
+<itemize>
+<item>
+<tt/debug/ -
+Supply more debugging information to <tt/syslog(3)/.
+
+<item>
+<tt/icase/ -
+Perform the password comparisons case insensitive.
+
+<item>
+<tt/dump/ -
+dump all the entries in the database to the log (eek,
+don't do this by default!)
+
+<item>
+<tt/db=XXXX/ -
+use the database found on pathname XXXX. Note that Berkeley DB usually adds the
+needed filename extension for you, so you should use something like <tt>/etc/foodata</tt>
+instead of <tt>/etc/foodata.db</tt>.
+
+</itemize>
+
+<tag><bf>Examples/suggested usage:</bf></tag>
+
+This is a normal ftp configuration file (usually placed as <tt>/etc/pam.d/ftp</tt>
+on most systems) that will accept for login users whose username/password pairs are
+provided in the <tt>/tmp/dbtest.db</tt> file:
+
+<tscreen>
+<verb>
+#%PAM-1.0
+auth required pam_listfile.so item=user sense=deny file=/etc/ftpusers onerr=succeed
+auth sufficient pam_userdb.so icase db=/tmp/dbtest
+auth required pam_pwdb.so shadow nullok try_first_pass
+auth required pam_shells.so
+account required pam_pwdb.so
+session required pam_pwdb.so
+</verb>
+</tscreen>
+
+</descrip>
+
+<!--
+End of sgml insert for this module.
+-->
diff --git a/contrib/libpam/doc/modules/pam_warn.sgml b/contrib/libpam/doc/modules/pam_warn.sgml
index 6e81f187f694..af01740c2f98 100644
--- a/contrib/libpam/doc/modules/pam_warn.sgml
+++ b/contrib/libpam/doc/modules/pam_warn.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_warn.sgml,v 1.1 1996/11/30 20:59:32 morgan Exp $
+ $Id: pam_warn.sgml,v 1.1.1.1 2000/06/20 22:11:05 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
-->
diff --git a/contrib/libpam/doc/modules/pam_wheel.sgml b/contrib/libpam/doc/modules/pam_wheel.sgml
index 9139695fec84..bf19a9bab808 100644
--- a/contrib/libpam/doc/modules/pam_wheel.sgml
+++ b/contrib/libpam/doc/modules/pam_wheel.sgml
@@ -1,5 +1,5 @@
<!--
- $Id: pam_wheel.sgml,v 1.3 1997/02/15 18:25:44 morgan Exp morgan $
+ $Id: pam_wheel.sgml,v 1.1.1.1 2000/06/20 22:11:05 agmorgan Exp $
This file was written by Andrew G. Morgan <morgan@parc.power.net>
from notes provided by Cristian Gafton.
@@ -56,10 +56,11 @@ Only permit root access to members of the wheel (<tt/gid=0/) group.
<tag><bf>Description:</bf></tag>
-This module is used to enforce the so-called wheel group. By default,
-it permits root access to the system if the applicant user is a member
-of the <tt/wheel/ group (better described as the group with group-id
-<tt/0/).
+This module is used to enforce the so-called <em/wheel/ group. By
+default, it permits root access to the system if the applicant user is
+a member of the <tt/wheel/ group (first, the module checks for the
+existence of a '<tt/wheel/' group. Otherwise the module defines the
+group with group-id <tt/0/ to be the <em/wheel/ group).
<p>
The action of the module may be modified from this default by one or
@@ -70,7 +71,7 @@ more of the following flags in the <tt>/etc/pam.conf</tt> file.
Supply more debugging information to <tt/syslog(3)/.
<item>
-<tt/use_id/ -
+<tt/use_uid/ -
This option modifies the behavior of the module by using the current
<tt/uid/ of the process and not the <tt/getlogin(3)/ name of the user.
This option is useful for being able to jump from one account to
diff --git a/contrib/libpam/doc/pam_appl.sgml b/contrib/libpam/doc/pam_appl.sgml
index 7c4170ae47ba..c32ee136b438 100644
--- a/contrib/libpam/doc/pam_appl.sgml
+++ b/contrib/libpam/doc/pam_appl.sgml
@@ -2,9 +2,9 @@
<!--
- $Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $
+ $Id: pam_appl.sgml,v 1.5 2001/03/19 01:46:41 agmorgan Exp $
- Copyright (C) Andrew G. Morgan 1996, 1997. All rights reserved.
+ Copyright (C) Andrew G. Morgan 1996-2001. All rights reserved.
Redistribution and use in source (sgml) and binary (derived) forms,
with or without modification, are permitted provided that the
@@ -45,8 +45,8 @@ DAMAGE.
<article>
<title>The Linux-PAM Application Developers' Guide
-<author>Andrew G. Morgan, <tt>morgan@linux.kernel.org</tt>
-<date>DRAFT v0.63 1998/1/18
+<author>Andrew G. Morgan, <tt>morgan@kernel.org</tt>
+<date>DRAFT v0.75 2001/03/18
<abstract>
This manual documents what an application developer needs to know
about the <bf>Linux-PAM</bf> library. It describes how an application
@@ -71,7 +71,7 @@ information:
<verb>
#include <security/pam_appl.h>
-cc -o application .... -lpam
+cc -o application .... -lpam -ldl
</verb>
</tscreen>
@@ -85,7 +85,7 @@ specific to the Linux-PAM distribution):
...
#include <security/pam_misc.h>
-cc -o application .... -lpam -lpam_misc
+cc -o application .... -lpam -lpam_misc -ldl
</verb>
</tscreen>
@@ -130,7 +130,7 @@ manage. In addition to authentication, PAM provides account
management, credential management, session management and
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 <bf>transparent</bf> to the
+services are provided in a manner that is <bf>transparent</bf> to
the application. That is to say, when the application is written, no
assumptions can be made about <em>how</em> the client will be
authenticated.
@@ -179,7 +179,7 @@ provided in a later section.
For example, the conversation function may be called by the PAM library
with a request to prompt the user for a password. Its job is to
reformat the prompt request into a form that the client will
-understand. In the case of <tt>ftpd</tt>, this will involve prefixing
+understand. In the case of <tt>ftpd</tt>, this might involve prefixing
the string with the number <tt>331</tt> and sending the request over
the network to a connected client. The conversation function will
then obtain any reply and, after extracting the typed password, will
@@ -218,9 +218,9 @@ PAM is also capable of setting and deleting the users credentials with
the call <tt>pam_setcred()</tt>. This function should always be
called after the user is authenticated and before service is offered
to the user. By convention, this should be the last call to the PAM
-library before service is given to the user. What exactly a
-credential is, is not well defined. However, some examples are given
-in the glossary below.
+library before the PAM session is opened. What exactly a credential
+is, is not well defined. However, some examples are given in the
+glossary below.
<sect>The public interface to <bf>Linux-PAM</bf>
@@ -233,7 +233,7 @@ some guiding remarks for programmers.
<sect1>What can be expected by the application
<p>
-Here we document those functions in the <bf/Linux-PAM/ library that
+Below we document those functions in the <bf/Linux-PAM/ library that
may be called from an application.
<sect2>Initialization of Linux-PAM
@@ -288,12 +288,16 @@ to cause a segmentation fault if accessed).
<p>
Under normal conditions the argument <tt/pam_status/ has the value
-PAM_SUCCESS, but in the event of an unsuccessful service application
-the approprite <bf/Linux-PAM/ error-return value should be used
-here.
-attempt its purpose is to be passed as an argument to the
-module specific function <tt/cleanup()/ (see the <bf/Linux-PAM/
-<htmlurl url="pam_modules.html" name="Module Developers' Guide">).
+PAM_SUCCESS, but in the event of an unsuccessful application for
+service the appropriate <bf/Linux-PAM/ error-return value should be
+used here. Note, <tt/pam_end()/ unconditionally shuts down the
+authentication stack associated with the <tt/pamh/ handle. The value
+taken by <tt/pam_status/ is used as an argument to the module specific
+callback functions, <tt/cleanup()/ (see the <bf/Linux-PAM/ <htmlurl
+url="pam_modules.html" name="Module Developers' Guide">). In this way,
+the module can be given notification of the pass/fail nature of the
+tear-down process, and perform any last minute tasks that are
+appropriate to the module before it is unlinked.
<sect2>Setting PAM items
<label id="pam-set-item-section">
@@ -316,33 +320,41 @@ extern int pam_set_item(pam_handle_t *pamh, int item_type,
<tag><tt/PAM_USER/</tag>
The user name
+<tag><tt/PAM_USER_PROMPT/</tag>
+ The string used when prompting for a user's name. The default
+value for this string is ``Please enter username: ''.
+
<tag><tt/PAM_TTY/</tag>
The terminal name: prefixed by <tt>/dev/</tt> if it is a
device file; for graphical, X-based, applications the value for this
item should be the <tt/&dollar;DISPLAY/ variable.
+<tag><tt/PAM_RUSER/</tag>
+ The requesting user's username
+
<tag><tt/PAM_RHOST/</tag>
- The remote host name
+ The requesting hostname (the hostname of the machine from which
+ the <tt/PAM_RUSER/ is requesting service)
<tag><tt/PAM_CONV/</tag>
The conversation structure (see section <ref
id="the-conversation-function" name="below">)
-<tag><tt/PAM_RUSER/</tag>
- The remote user name
-
-<tag><tt/PAM_USER_PROMPT/</tag>
- The string used when prompting for a user's name. The default
-value for this string is ``Please enter username: ''.
+<tag><tt/PAM_FAIL_DELAY/</tag> A function pointer to redirect
+ centrally managed failure delays (see section <ref
+ id="the-failure-delay-function" name="below">).
</descrip>
<p>
-For all <tt/item_type/s, other than <tt/PAM_CONV/, <tt/item/ is a
-pointer to a <tt>&lt;NUL&gt;</tt> terminated character string. In the
-case of <tt/PAM_CONV/, <tt/item/ points to an initialized
-<tt/pam_conv/ structure (see section <ref
-id="the-conversation-function" name="below">).
+For all <tt/item_type/s, other than <tt/PAM_CONV/ and
+<tt/PAM_FAIL_DELAY/, <tt/item/ is a pointer to a <tt>&lt;NUL&gt;</tt>
+terminated character string. In the case of <tt/PAM_CONV/, <tt/item/
+points to an initialized <tt/pam_conv/ structure (see section <ref
+id="the-conversation-function" name="below">). In the case of
+<tt/PAM_FAIL_DELAY/, <tt/item/ is a function pointer: <tt/void
+(*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr)/ (see
+section <ref id="the-failure-delay-function" name="below">).
<p>
A successful call to this function returns <tt/PAM_SUCCESS/. However,
@@ -350,13 +362,17 @@ the application should expect one of the following errors:
<p>
<descrip>
+<tag><tt/PAM_SYSTEM_ERR/</tag>
+ The <tt/pam_handle_t/ passed as a first argument to this
+ function was invalid.
<tag><tt/PAM_PERM_DENIED/</tag>
An attempt was made to replace the conversation structure with
-a <tt/NULL/ value.
+ a <tt/NULL/ value.
<tag><tt/PAM_BUF_ERR/</tag>
The function ran out of memory making a copy of the item.
<tag><tt/PAM_BAD_ITEM/</tag>
- The application attempted to set an undefined item.
+ The application attempted to set an undefined or inaccessible
+ item.
</descrip>
<sect2>Getting PAM items
@@ -375,9 +391,31 @@ This function is used to obtain the value of the indicated
<tt/item_type/. Upon successful return, <tt/*item/ contains a pointer
to the value of the corresponding item. Note, this is a pointer to
the <em/actual/ data and should <em/not/ be <tt/free()/'ed or
-over-written! A successful call is signaled by a return value of
-<tt/PAM_SUCCESS/. If an attempt is made to get an undefined item,
-<tt/PAM_BAD_ITEM/ is returned.
+over-written!
+
+<p>
+A successful call is signaled by a return value of <tt/PAM_SUCCESS/.
+However, the application should expect one of the following errors:
+
+<p>
+<descrip>
+<tag><tt/PAM_SYSTEM_ERR/</tag>
+ The <tt/pam_handle_t/ passed as a first argument to this
+ function was invalid.
+<tag><tt/PAM_PERM_DENIED/</tag>
+ The value of <tt/item/ was <tt/NULL/.
+<tag><tt/PAM_BAD_ITEM/</tag>
+ The application attempted to set an undefined or inaccessible
+ item.
+</descrip>
+
+<p>
+Note, in the case of an error, the contents of <tt/item/ is not
+modified - that is, it retains its pre-call value. One should take
+care to initialize this value prior to calling
+<tt/pam_get_item()/. Since, if its value - despite the
+<tt/pam_get_item()/ function failing - is to be used the consequences
+are undefined.
<sect2>Understanding errors
<label id="pam-strerror-section">
@@ -395,6 +433,7 @@ error associated with the argument <tt/errnum/. If the error is not
recognized ``<tt/Unknown Linux-PAM error/'' is returned.
<sect2>Planning for delays
+<label id="the-failure-delay-function">
<p>
<tscreen>
@@ -410,9 +449,9 @@ is returned to the application. When using this function the
application programmer should check if it is available with,
<tscreen>
<verb>
-#ifdef HAVE_PAM_FAIL_DELAY
+#ifdef PAM_FAIL_DELAY
....
-#endif /* HAVE_PAM_FAIL_DELAY */
+#endif /* PAM_FAIL_DELAY */
</verb>
</tscreen>
@@ -420,14 +459,14 @@ application programmer should check if it is available with,
<p>
Generally, an application requests that a user is authenticated by
<bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or
-<tt/pam_chauthtok()/. These functions calls each of the <em/stacked/
-authentication modules listed in the <tt>/etc/pam.conf</tt> file. As
-directed by this file, one of more of the modules may fail causing the
-<tt/pam_...()/ call to return an error. It is desirable for there to
-also be a pause before the application continues. The principal reason
-for such a delay is security: a delay acts to discourage <em/brute
-force/ dictionary attacks primarily, but also helps hinder
-<em/timed/ (covert channel) attacks.
+<tt/pam_chauthtok()/. These functions call each of the <em/stacked/
+authentication modules listed in the relevant <bf/Linux-PAM/
+configuration file. As directed by this file, one of more of the
+modules may fail causing the <tt/pam_...()/ call to return an error.
+It is desirable for there to also be a pause before the application
+continues. The principal reason for such a delay is security: a delay
+acts to discourage <em/brute force/ dictionary attacks primarily, but
+also helps hinder <em/timed/ (covert channel) attacks.
<p>
The <tt/pam_fail_delay()/ function provides the mechanism by which an
@@ -441,6 +480,34 @@ randomly distributed (by up to 25%) about this longest value.
Independent of success, the delay time is reset to its zero default
value when <bf/Linux-PAM/ returns control to the application.
+<p>
+For applications written with a single thread that are event driven in
+nature, <tt/libpam/ generating this delay may be undesirable. Instead,
+the application may want to register the delay in some other way. For
+example, in a single threaded server that serves multiple
+authentication requests from a single event loop, the application
+might want to simply mark a given connection as blocked until an
+application timer expires. For this reason, <bf/Linux-PAM/ supplies
+the <tt/PAM_FAIL_DELAY/ item. It can be queried and set with
+<tt/pam_get_item()/ and <tt/pam_set_item()/ respectively. The value
+used to set it should be a function pointer of the following
+prototype:
+
+<tscreen>
+<verb>
+void (*delay_fn)(int retval, unsigned usec_delay, void *appdata_ptr);
+</verb>
+</tscreen>
+
+The arguments being the <tt/retval/ return code of the module stack,
+the <tt/usec_delay/ micro-second delay that libpam is requesting and
+the <tt/appdata_ptr/ that the application has associated with the
+current <tt/pamh/ (<tt/pam_handle_t/). This last value was set by the
+application when it called <tt/pam_start/ or explicitly with
+<tt/pam_set_item(... , PAM_CONV, ...)/. Note, if <tt/PAM_FAIL_DELAY/
+is unset (or set to <tt/NULL/), then <tt/libpam/ will perform any
+delay.
+
<sect2>Authenticating the user
<p>
@@ -502,7 +569,7 @@ extern int pam_setcred(pam_handle_t *pamh, int flags);
<p>
This function is used to set the module-specific credentials of the
user. It is usually called after the user has been authenticated,
-after the account management function has been called and after a
+after the account management function has been called but before a
session has been opened for the user.
<p>
@@ -583,7 +650,7 @@ this. In such cases, the user should be denied access until such time
as they can update their password.
<tag><tt/PAM_ACCT_EXPIRED/</tag>
- The user is no longer permitted access to the system.
+ The user is no longer permitted to access the system.
<tag><tt/PAM_AUTH_ERR/</tag>
There was an authentication error.
@@ -667,7 +734,7 @@ extern int pam_open_session(pam_handle_t *pamh, int flags);
<p>
This function is used to indicate that an authenticated session has
-begun. It is used to inform the module that the user is currently in
+begun. It is used to inform the modules that the user is currently in
a session. It should be possible for the <bf>Linux-PAM</bf> library
to open a session and close the same session (see section <ref
id="pam-close-session-section" name="below">) from different
@@ -694,14 +761,15 @@ extern int pam_close_session(pam_handle_t *pamh, int flags);
<p>
This function is used to indicate that an authenticated session has
-ended. It is used to inform the module that the user is exiting a
+ended. It is used to inform the modules that the user is exiting a
session. It should be possible for the <bf>Linux-PAM</bf> library to
open a session and close the same session from different applications.
<p>
-Currently, this function simply calls each of the corresponding
-functions of the loaded modules. The only valid flag is
-<tt/PAM_SILENT/ and this is, of course, <em/optional/.
+This function simply calls each of the corresponding functions of the
+loaded modules in the same order that they were invoked with
+<tt/pam_open_session()/. The only valid flag is <tt/PAM_SILENT/ and
+this is, of course, <em/optional/.
<p>
If any of the <em/required/ loaded modules are unable to close a
@@ -718,14 +786,6 @@ extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
</tscreen>
<p>
-<em>
-Warning, the environment support in <bf/Linux-PAM/ is based solely
-on a six line email from the developers at Sun. Its interface is
-likely to be generally correct, however, the details are likely to be
-changed as more information becomes available.
-</em>
-
-<p>
This function attempts to (re)set a <bf/Linux-PAM/ environment
variable. The <tt/name_value/ argument is a single <tt/NUL/ terminated
string of one of the following forms:
@@ -746,7 +806,7 @@ setting.
<tag>``<tt/NAME/''</tag>
Without an `<tt/=/' the <tt/pam_putenv()/ function will delete the
-correspoding variable from the <bf/Linux-PAM/ environment.
+corresponding variable from the <bf/Linux-PAM/ environment.
</descrip>
@@ -927,7 +987,7 @@ to display some text.
<p>
Post Linux-PAM-0.59 (and in the interests of compatibility with
-Sunsoft). The number of resposes is always equal to the <tt/num_msg/
+Sunsoft). The number of responses is always equal to the <tt/num_msg/
conversation function argument. This is slightly easier to program
but does require that the response array is <tt/free(3)/'d after every
call to the conversation function. The index of the responses
@@ -969,6 +1029,13 @@ generated.
<sect>Security issues of <bf>Linux-PAM</bf>
<p>
+PAM, from the perspective of an application, is a convenient API for
+authenticating users. PAM modules generally have no increased
+privilege over that possessed by the application that is making use of
+it. For this reason, the application must take ultimate responsibility
+for protecting the environment in which PAM operates.
+
+<p>
A poorly (or maliciously) written application can defeat any
<bf/Linux-PAM/ module's authentication mechanisms by simply ignoring
it's return values. It is the applications task and responsibility to
@@ -994,17 +1061,17 @@ library, or copy the structure contents to some safe area of memory
before passing control to the <bf/Linux-PAM/ library.
<p>
-Two function classes that fall into this category are
+Two important function classes that fall into this category are
<tt>getpwnam(3)</tt> and <tt>syslog(3)</tt>.
<sect1>Choice of a service name
<p>
When picking the <em/service-name/ that corresponds to the first entry
-in the <tt>/etc/pam.conf</tt> file, the application programmer should
-<bf/avoid/ the temptation of choosing something related to
+in the <bf/Linux-PAM/ configuration file, the application programmer
+should <bf/avoid/ the temptation of choosing something related to
<tt/argv[0]/. It is a trivial matter for any user to invoke any
-application on a system under a different name -- this should not be
+application on a system under a different name and this should not be
permitted to cause a security breach.
<p>
@@ -1019,14 +1086,14 @@ ln -s /target/application ./preferred_name
and then <em/run/ <tt>./preferred_name</tt>
<p>
-By studying the <bf/Linux-PAM/ configuration file,
-<tt>/etc/pam.conf</tt>, an attacker can choose the <tt/preferred_name/
-to be that of a service enjoying minimal protection; for example a
-game which uses <bf/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 dictating which authentication scheme
-the service uses. Needless to say, this is not a secure situation.
+By studying the <bf/Linux-PAM/ configuration file(s), an attacker can
+choose the <tt/preferred_name/ to be that of a service enjoying
+minimal protection; for example a game which uses <bf/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 dictating
+which authentication scheme the service uses. Needless to say, this
+is not a secure situation.
<p>
The conclusion is that the application developer should carefully
@@ -1051,16 +1118,40 @@ identity of the user once the service is granted.
<p>
The need for keeping tabs on these identities is clearly an issue of
-security. Basically, the identity of the user requesting a service
-should be the current <tt/uid/ (userid) of the running process; the
-identity of the privilege granting user is the <tt/euid/ (effective
-userid) of the running process; the identity of the user, under whose
-name the service will be executed, is given by the contents of the
-<tt/PAM_USER/ <tt/pam_get_item(2)/.
-
-<p>
-In addition the identity of a remote user, requesting the service from
-a distant location, will be placed in the <tt/PAM_RUSER/ item.
+security. One convention that is actively used by some modules is
+that the identity of the user requesting a service should be the
+current <tt/uid/ (userid) of the running process; the identity of the
+privilege granting user is the <tt/euid/ (effective userid) of the
+running process; the identity of the user, under whose name the
+service will be executed, is given by the contents of the
+<tt/PAM_USER/ <tt/pam_get_item(3)/.
+
+<p>
+For network-serving databases and other applications that provide
+their own security model (independent of the OS kernel) the above
+scheme is insufficient to identify the requesting user.
+
+<p>
+A more portable solution to storing the identity of the requesting
+user is to use the <tt/PAM_RUSER/ <tt/pam_get_item(3)/. The
+application should supply this value before attempting to authenticate
+the user with <tt/pam_authenticate()/. How well this name can be
+trusted will ultimately be at the discretion of the local
+administrator (who configures PAM for your application) and a selected
+module may attempt to override the value where it can obtain more
+reliable data. If an application is unable to determine the identity
+of the requesting entity/user, it should not call <tt/pam_set_item(3)/
+to set <tt/PAM_RUSER/.
+
+<p>
+In addition to the <tt/PAM_RUSER/ item, the application should supply
+the <tt/PAM_RHOST/ (<em/requesting host/) item. As a general rule, the
+following convention for its value can be assumed: <tt/&lt;unset&gt;/
+= unknown; <tt/localhost/ = invoked directly from the local system;
+<em/other.place.xyz/ = some component of the user's connection
+originates from this remote/requesting host. At present, PAM has no
+established convention for indicating whether the application supports
+a trusted path to communication from this host.
<sect1>Sufficient resources
@@ -1072,6 +1163,13 @@ it should fail gracefully, or request additional resources.
Specifically, the quantities manipulated by the <tt/setrlimit(2)/
family of commands should be taken into consideration.
+<p>
+This is also true of conversation prompts. The application should not
+accept prompts of arbitrary length with out checking for resource
+allocation failure and dealing with such extreme conditions gracefully
+and in a mannor that preserves the PAM API. Such tolerance may be
+especially important when attempting to track a malicious adversary.
+
<sect>A library of miscellaneous helper functions
<label id="libpam-misc-section">
@@ -1242,7 +1340,7 @@ The following is extracted from an email. I'll tidy it up later.
<p>
The point of PAM is that the application is not supposed to have any
-idea how the attatched authentication modules will choose to
+idea how the attached authentication modules will choose to
authenticate the user. So all they can do is provide a conversation
function that will talk directly to the user(client) on the modules'
behalf.
@@ -1256,10 +1354,10 @@ point is that the retinal scanner is an ideal task for a "module".
<p>
While it is true that a pop-daemon program is designed with the POP
-protocol in mind and no-one ever considered attatching a retinal
+protocol in mind and no-one ever considered attaching a retinal
scanner to it, it is also the case that the "clean" PAM'ification of
such a daemon would allow for the possibility of a scanner module
-being be attatched to it. The point being that the "standard"
+being be attached to it. The point being that the "standard"
pop-authentication protocol(s) [which will be needed to satisfy
inflexible/legacy clients] would be supported by inserting an
appropriate pam_qpopper module(s). However, having rewritten popd
@@ -1280,7 +1378,7 @@ of the authentication procedure (how many passwords etc..) the
exchange protocol (prefixes to prompts etc., numbers like 331 in the
case of ftpd) and what is part of the service that the application
delivers. PAM really needs to have total control in the
-authentication "proceedure", the conversation function should only
+authentication "procedure", the conversation function should only
deal with reformatting user prompts and extracting responses from raw
input.
@@ -1459,30 +1557,41 @@ This document was written by Andrew G. Morgan
<!-- insert credits here -->
<!--
an sgml list of people to credit for their contributions to Linux-PAM
- $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
+ $Id: pam_appl.sgml,v 1.5 2001/03/19 01:46:41 agmorgan Exp $
-->
+Chris Adams,
Peter Allgeyer,
Tim Baverstock,
+Tim Berger,
Craig S. Bell,
Derrick J. Brashear,
Ben Buxton,
+Seth Chaiklin,
Oliver Crow,
Chris Dent,
Marc Ewing,
Cristian Gafton,
+Emmanuel Galanos,
+Brad M. Garcia,
Eric Hester,
Roger Hu,
Eric Jacksch,
Michael K. Johnson,
David Kinchlea,
+Olaf Kirch,
+Marcin Korzonek,
+Stephen Langasek,
Nicolai Langfeldt,
Elliot Lee,
+Luke Kenneth Casson Leighton,
Al Longyear,
Ingo Luetkebohle,
Marek Michalkiewicz,
+Robert Milkowski,
Aleph One,
Martin Pool,
Sean Reifschneider,
+Jan Rekorajski,
Erik Troan,
Theodore Ts'o,
Jeff Uphoff,
@@ -1495,7 +1604,6 @@ Joseph S. D. Yao
and
Alex O. Yuriev.
-
<p>
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
@@ -1512,7 +1620,7 @@ credited for all the good work they have done.
<sect>Copyright information for this document
<p>
-Copyright (c) Andrew G. Morgan 1996, 1997. All rights reserved.
+Copyright (c) Andrew G. Morgan 1996-9. All rights reserved.
<newline>
Email: <tt>&lt;morgan@transmeta.com&gt;</tt>
@@ -1562,6 +1670,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<p>
-<tt>$Id: pam_appl.sgml,v 1.16 1997/04/05 06:49:14 morgan Exp morgan $</tt>
+<tt>$Id: pam_appl.sgml,v 1.5 2001/03/19 01:46:41 agmorgan Exp $</tt>
</article>
diff --git a/contrib/libpam/doc/pam_modules.sgml b/contrib/libpam/doc/pam_modules.sgml
index 418b09beafd3..609916c4470d 100644
--- a/contrib/libpam/doc/pam_modules.sgml
+++ b/contrib/libpam/doc/pam_modules.sgml
@@ -2,9 +2,9 @@
<!--
- $Id: pam_modules.sgml,v 1.19 1997/04/05 06:49:14 morgan Exp morgan $
+ $Id: pam_modules.sgml,v 1.6 2001/02/22 04:58:51 agmorgan Exp $
- Copyright (c) Andrew G. Morgan 1996, 1997. All rights reserved.
+ Copyright (c) Andrew G. Morgan 1996-2001. All rights reserved.
** some sections, in this document, were contributed by other
** authors. They carry individual copyrights.
@@ -48,8 +48,8 @@ DAMAGE.
<article>
<title>The Linux-PAM Module Writers' Guide
-<author>Andrew G. Morgan, <tt>morgan@transmeta.com</tt>
-<date>DRAFT v0.59 1997/10/17
+<author>Andrew G. Morgan, <tt>morgan@kernel.org</tt>
+<date>DRAFT v0.75 2001/02/21
<abstract>
This manual documents what a programmer needs to know in order to
write a module that conforms to the <bf/Linux-PAM/ standard. It also
@@ -68,7 +68,7 @@ programmer.
#include <security/pam_modules.h>
gcc -fPIC -c pam_module-name.c
-ld -x --shared -o pam_module-name.so pam_module-name.o -lpam
+ld -x --shared -o pam_module-name.so pam_module-name.o
</verb>
</tscreen>
@@ -122,13 +122,11 @@ Setting data
Synopsis:
<tscreen>
<verb>
-extern int pam_set_data(pam_handle_t *pamh
- , const char *module_data_name
- , void *data
- , void (*cleanup)(pam_handle_t *pamh
- , void *data
- , int error_status)
- );
+extern int pam_set_data(pam_handle_t *pamh,
+ const char *module_data_name,
+ void *data,
+ void (*cleanup)(pam_handle_t *pamh,
+ void *data, int error_status) );
</verb>
</tscreen>
@@ -159,16 +157,15 @@ module may choose to delete the ticket file (<em/authentication
failure/) or leave it in place.
<p>
-(*This paragraph is currently under advisement with Sun*) The
-<tt/error_status/ may have been logically OR'd with either of the
+The <tt/error_status/ may have been logically OR'd with either of the
following two values:
<p>
<descrip>
<tag><tt/PAM_DATA_REPLACE/</tag>
When a data item is being replaced (through a second call to
-<tt/pam_set_data()/) this mask is used is used. Otherwise, the call is
-assumed to be from <tt/pam_end()/.
+<tt/pam_set_data()/) this mask is used. Otherwise, the call is assumed
+to be from <tt/pam_end()/.
<tag><tt/PAM_DATA_SILENT/</tag>
Which indicates that the process would prefer to perform the
@@ -185,10 +182,9 @@ Getting data
Synopsis:
<tscreen>
<verb>
-extern int pam_get_data(const pam_handle_t *pamh
- , const char *module_data_name
- , const void **data
- );
+extern int pam_get_data(const pam_handle_t *pamh,
+ const char *module_data_name,
+ const void **data);
</verb>
</tscreen>
@@ -211,10 +207,9 @@ Setting items
Synopsis:
<tscreen>
<verb>
-extern int pam_set_item(pam_handle_t *pamh
- , int item_type
- , const void *item
- );
+extern int pam_set_item(pam_handle_t *pamh,
+ int item_type,
+ const void *item);
</verb>
</tscreen>
@@ -231,8 +226,8 @@ following two <tt/item_type/s:
<descrip>
<tag><tt/PAM_AUTHTOK/</tag>
-The authentication token (password). This token should be ignored by
-all module functions besides <tt/pam_sm_authenticate()/ and
+The authentication token (often a password). This token should be
+ignored by all module functions besides <tt/pam_sm_authenticate()/ and
<tt/pam_sm_chauthtok()/. In the former function it is used to pass the
most recent authentication token from one stacked module to
another. In the latter function the token is used for another
@@ -262,10 +257,9 @@ Getting items
Synopsis:
<tscreen>
<verb>
-extern int pam_get_item(const pam_handle_t *pamh
- , int item_type
- , const void **item
- );
+extern int pam_get_item(const pam_handle_t *pamh,
+ int item_type,
+ const void **item);
</verb>
</tscreen>
@@ -346,10 +340,9 @@ The return values for this function are listed in the
Synopsis:
<tscreen>
<verb>
-extern int pam_get_user(pam_handle_t *pamh
- , const char **user
- , const char *prompt
- );
+extern int pam_get_user(pam_handle_t *pamh,
+ const char **user,
+ const char *prompt);
</verb>
</tscreen>
@@ -386,6 +379,27 @@ Also, in addition, it should be noted that this function sets the
<tt/PAM_USER/ item that is associated with the <tt/pam_[gs]et_item()/
function.
+<p>
+The return value of this function is one of the following:
+<itemize>
+
+<item> <tt/PAM_SUCCESS/ - username obtained.
+
+<item> <tt/PAM_CONV_AGAIN/ - converstation did not complete and the
+caller is required to return control to the application, until such
+time as the application has completed the conversation process. A
+module calling <tt/pam_get_user()/ that obtains this return code,
+should return <tt/PAM_INCOMPLETE/ and be prepared (when invoked the
+next time) to recall <tt/pam_get_user()/ to fill in the user's name,
+and then pick up where it left off as if nothing had happened. This
+procedure is needed to support an event-driven application programming
+model.
+
+<item> <tt/PAM_CONV_ERR/ - the conversation method supplied by the
+application failed to obtain the username.
+
+</itemize>
+
<sect2>Setting a Linux-PAM environment variable
<p>
@@ -397,7 +411,7 @@ extern int pam_putenv(pam_handle_t *pamh, const char *name_value);
</tscreen>
<p>
-<bf/Linux-PAM/ (0.54+) comes equipped with a series of functions for
+<bf/Linux-PAM/ comes equipped with a series of functions for
maintaining a set of <em/environment/ variables. The environment is
initialized by the call to <tt/pam_start()/ and is <bf/erased/ with a
call to <tt/pam_end()/. This <em/environment/ is associated with the
@@ -515,23 +529,23 @@ is returned to the application. When using this function the module
programmer should check if it is available with,
<tscreen>
<verb>
-#ifdef HAVE_PAM_FAIL_DELAY
+#ifdef PAM_FAIL_DELAY
....
-#endif /* HAVE_PAM_FAIL_DELAY */
+#endif /* PAM_FAIL_DELAY */
</verb>
</tscreen>
<p>
Generally, an application requests that a user is authenticated by
<bf/Linux-PAM/ through a call to <tt/pam_authenticate()/ or
-<tt/pam_chauthtok()/. These functions calls each of the <em/stacked/
-authentication modules listed in the <tt>/etc/pam.conf</tt> file. As
-directed by this file, one of more of the modules may fail causing the
-<tt/pam_...()/ call to return an error. It is desirable for there to
-also be a pause before the application continues. The principal reason
-for such a delay is security: a delay acts to discourage <em/brute
-force/ dictionary attacks primarily, but also helps hinder
-<em/timed/ (covert channel) attacks.
+<tt/pam_chauthtok()/. These functions call each of the <em/stacked/
+authentication modules listed in the <bf/Linux-PAM/ configuration
+file. As directed by this file, one of more of the modules may fail
+causing the <tt/pam_...()/ call to return an error. It is desirable
+for there to also be a pause before the application continues. The
+principal reason for such a delay is security: a delay acts to
+discourage <em/brute force/ dictionary attacks primarily, but also
+helps hinder <em/timed/ (cf. covert channel) attacks.
<p>
The <tt/pam_fail_delay()/ function provides the mechanism by which an
@@ -677,8 +691,9 @@ This function performs the task of altering the credentials of the
user with respect to the corresponding authorization
scheme. Generally, an authentication module may have access to more
information about a user than their authentication token. This
-function is used to append such information to the application. It
-should only be called <em/after/ the user has been authenticated.
+function is used to make such information available to the
+application. It should only be called <em/after/ the user has been
+authenticated but before a session has been established.
<p>
Permitted flags, one of which, may be logically OR'd with
@@ -696,6 +711,28 @@ Permitted flags, one of which, may be logically OR'd with
</descrip>
<p>
+Prior to <bf/Linux-PAM-0.75/, and due to a deficiency with the way the
+<tt/auth/ stack was handled in the case of the setcred stack being
+processed, the module was required to attempt to return the same error
+code as <tt/pam_sm_authenticate/ did. This was necessary to preserve
+the logic followed by libpam as it executes the stack of
+<em/authentication/ modules, when the application called either
+<tt/pam_authenticate()/ or <tt/pam_setcred()/. Failing to do this,
+led to confusion on the part of the System Administrator.
+
+<p>
+For <bf/Linux-PAM-0.75/ and later, libpam handles the credential stack
+much more sanely. The way the <tt/auth/ stack is navigated in order to
+evaluate the <tt/pam_setcred()/ function call, independent of the
+<tt/pam_sm_setcred()/ return codes, is exactly the same way that it
+was navigated when evaluating the <tt/pam_authenticate()/ library
+call. Typically, if a stack entry was ignored in evaluating
+<tt/pam_authenticate()/, it will be ignored when libpam evaluates the
+<tt/pam_setcred()/ function call. Otherwise, the return codes from
+each module specific <tt/pam_sm_setcred()/ call are treated as
+<tt/required/.
+
+<p>
Besides <tt/PAM_SUCCESS/, the module may return one of the following
errors:
@@ -710,6 +747,11 @@ errors:
This module was unable to set the credentials of the user.
</descrip>
+<p>
+these, non-<tt/PAM_SUCCESS/, return values will typically lead to the
+credential stack <em/failing/. The first such error will dominate in
+the return value of <tt/pam_setcred()/.
+
</itemize>
<sect1> Account management
@@ -953,6 +995,20 @@ executed module). Then, with logical-exclusive-or, use the result as a
<em/key/ to safely store/retrieve the authentication token for this
module in/from a local file <em/etc/. .
+<tag><tt/expose_account/</tag>
+
+<p>
+In general the leakage of some information about user accounts is not
+a secure policy for modules to adopt. Sometimes information such as
+users names or home directories, or preferred shell, can be used to
+attack a user's account. In some circumstances, however, this sort of
+information is not deemed a threat: displaying a user's full name when
+asking them for a password in a secured environment could also be
+called being 'friendly'. The <tt/expose_account/ argument is a
+standard module argument to encourage a module to be less discrete
+about account information as it is deemed appropriate by the local
+administrator.
+
</descrip>
<sect>Programming notes
@@ -1238,13 +1294,22 @@ endif
For some further examples, see the <tt>modules</tt> subdirectory of
the current <bf/Linux-PAM/ distribution.
-<p>
<sect>An example module file
<p>
-<em>
-perhaps this should point to a place in the file structure!?
-</em>
+At some point, we may include a fully commented example of a module in
+this document. For now, we point the reader to these two locations in
+the public CVS repository:
+<itemize>
+<item> A module that always succeeds: <tt><htmlurl
+url="http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/Linux-PAM/modules/pam_permit/?cvsroot=pam"
+name="http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/Linux-PAM/modules/pam_permit/?cvsroot=pam"
+></tt>
+<item> A module that always fails: <tt><htmlurl
+url="http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/Linux-PAM/modules/pam_deny/?cvsroot=pam"
+name="http://cvs.sourceforge.net/cgi-bin/cvsweb.cgi/Linux-PAM/modules/pam_deny/?cvsroot=pam"
+></tt>
+</itemize>
<sect>Files
@@ -1314,33 +1379,41 @@ This document was written by Andrew G. Morgan
<!-- insert credits here -->
<!--
an sgml list of people to credit for their contributions to Linux-PAM
+ $Id: pam_modules.sgml,v 1.6 2001/02/22 04:58:51 agmorgan Exp $
-->
-<!--
- an sgml list of people to credit for their contributions to Linux-PAM
- $Id: CREDITS,v 1.4 1997/04/05 06:47:26 morgan Exp morgan $
- -->
+Chris Adams,
Peter Allgeyer,
Tim Baverstock,
+Tim Berger,
Craig S. Bell,
Derrick J. Brashear,
Ben Buxton,
+Seth Chaiklin,
Oliver Crow,
Chris Dent,
Marc Ewing,
Cristian Gafton,
+Emmanuel Galanos,
+Brad M. Garcia,
Eric Hester,
Roger Hu,
Eric Jacksch,
Michael K. Johnson,
David Kinchlea,
+Olaf Kirch,
+Marcin Korzonek,
+Stephen Langasek,
Nicolai Langfeldt,
Elliot Lee,
+Luke Kenneth Casson Leighton,
Al Longyear,
Ingo Luetkebohle,
Marek Michalkiewicz,
+Robert Milkowski,
Aleph One,
Martin Pool,
Sean Reifschneider,
+Jan Rekorajski,
Erik Troan,
Theodore Ts'o,
Jeff Uphoff,
@@ -1420,6 +1493,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<p>
-<tt>$Id: pam_modules.sgml,v 1.19 1997/04/05 06:49:14 morgan Exp morgan $</tt>
+<tt>$Id: pam_modules.sgml,v 1.6 2001/02/22 04:58:51 agmorgan Exp $</tt>
</article>
diff --git a/contrib/libpam/doc/pam_source.sgml b/contrib/libpam/doc/pam_source.sgml
index 093998a0aad1..5e4be447bb32 100644
--- a/contrib/libpam/doc/pam_source.sgml
+++ b/contrib/libpam/doc/pam_source.sgml
@@ -2,9 +2,9 @@
<!--
- $Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $
+ $Id: pam_source.sgml,v 1.5 2001/03/19 01:46:41 agmorgan Exp $
- Copyright (c) Andrew G. Morgan 1996,1997. All rights reserved.
+ Copyright (c) Andrew G. Morgan 1996-2001. All rights reserved.
Redistribution and use in source (sgml) and binary (derived) forms,
with or without modification, are permitted provided that the
@@ -45,8 +45,8 @@ DAMAGE.
<article>
<title>The Linux-PAM System Administrators' Guide
-<author>Andrew G. Morgan, <tt>morgan@linux.kernel.org</tt>
-<date>DRAFT v0.59 1998/1/7
+<author>Andrew G. Morgan, <tt>morgan@kernel.org</tt>
+<date>DRAFT v0.75 2001/03/18
<abstract>
This manual documents what a system-administrator needs to know about
the <bf>Linux-PAM</bf> library. It covers the correct syntax of the
@@ -140,10 +140,10 @@ command shell (<em>bash, tcsh, zsh, etc.</em>) running with the
identity of the user.
<p>
-Traditinally, the former step is achieved by the <em/login/
+Traditionally, the former step is achieved by the <em/login/
application prompting the user for a password and then verifying that
-it agrees with that located on the system; hence verifying that the
-so far as the system is concerned the user is who they claim to be.
+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 <bf/Linux-PAM/.
<p>
@@ -215,12 +215,122 @@ configured authentication method. The <bf/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 configuaration file. These modules, when
+the order they appear in the configuration file. These modules, when
called by <bf/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
<em/conversation/ function.
+<sect1>Getting started
+
+<p>
+The following text was contributed by Seth Chaiklin:
+<tscreen>
+<verb>
+To this point, we have described how PAM should work in an
+ideal world, in which all applications are coded properly.
+However, at the present time (October 1998), this is far
+from the case. Therefore, here are some practical considerations
+in trying to use PAM in your system.
+
+Why bother, is it really worth all the trouble?
+
+If you running Linux as a single user system, or in an
+environment where all the users are trusted, then there
+is no real advantage for using PAM.
+</verb>
+</tscreen>
+
+<p>
+<BF>Ed:</BF> there is actually an advantage since you can <em/dummy
+down/ the authentication to the point where you don't have
+any... Almost like Win95.
+<p>
+In a networked environment, it is clear that you need to think a
+little more about how users etc., are authenticated:]
+
+<p>
+<tscreen>
+<verb>
+If you are running Linux as a server, where several different
+services are being provided (e.g., WWW with areas restricted by
+password control, PPP), then there can be some real and interesting
+value for PAM. In particular, through the use of modules, PAM can
+enable a program to search through several different password
+databases, even if that program is not explicitly coded for
+that particular database. Here are some examples of the possibilities
+that this enables.
+
+ o Apache has a module that provides PAM services. Now
+ authentication
+ to use particular directories can be conducted by PAM, which
+ means that the range of modules that are available to PAM can
+ be used, including RADIUS, NIS, NCP (which means that Novell
+ password databases can be used).
+
+ o pppd has a PAMified version (available from RedHat) Now it is
+ possible to use a series of databases to authenticate ppp users.
+ In addition to the normal Linux-based password databases (such
+ as /etc/passwd and /etc/shadow), you can use PAM modules to
+ authenticate against Novell password databases or NT-based
+ password databases.
+
+ o The preceding two examples can be combined. Imagaine that the
+ persons in your office/department are already registered with a
+ username and password in a Novell or NT LAN. If you wanted to
+ use this database on your Linux server (for PPP access, for
+ web access, or even for normal shell access), you can use PAM
+ to authenticate against this existing database, rather than
+ maintain a separate database on both Linux and the LAN server.
+
+
+Can I use PAM for any program that requires authentication?
+
+Yes and no. Yes, if you have access to the source code, and can
+add the appropriate PAM functions. No, if you do not have access
+to the source code, and the binary does not have the PAM functions
+included.
+
+In other words, if a program is going to use PAM, then it has to
+have PAM functions explicitly coded into the program. If they
+are not, then it is not possible to use PAM.
+
+How can I tell whether a program has PAM coded into it or not?
+
+A quick-and-dirty (but not always reliable) method is to ldd
+<programname>
+If libpam and libpam_misc are not among the libraries that the program
+uses, then it is not going to work with PAM. However, it is possible
+that the libraries are included, but there are still problems, because
+the PAM coding in the program does not work as it should. So a
+more reliable method is to make the follow tests.
+
+In the /etc/pam.d directory, one needs to make a configuration file
+for the program that one wants to run. The exact name of the
+configuration
+file is hard-coded into the program. Usually, it is the same name as
+the
+program, but not always. For sake of illustration, let's assume that
+the program is named "pamprog" and the name of the configuration file
+is /etc/pam.d/pamprog.
+
+In the /etc/pam.d/pamprog but the following two lines:
+
+auth required pam_permit.so
+auth required pam_warn.so
+
+
+Now try to use pamprog. The first line in the configuration file
+says that all users are permitted. The second line will write a
+warning to your syslog file (or whether you syslog is writing
+
+messages). If this test succeeds, then you know that you have
+a program that can understand pam, and you can start the more
+interesting work of deciding how to stack modules in your
+/etc/pam.d/pamprog file.
+</verb>
+</tscreen>
+
<sect>The Linux-PAM configuration file
<label id="configuration">
@@ -363,9 +473,13 @@ is not deemed as fatal to satisfying the application that this
<item> <tt/optional/; as its name suggests, this <tt/control-flag/
marks the module as not being critical to the success or failure of
-the user's application for service. However, in the absence of any
-successes of previous or subsequent stacked modules this module will
-determine the nature of the response to the application.
+the user's application for service. In general, <bf/Linux-PAM/
+ignores such a module when determining if the module stack will
+succeed or fail. However, in the absence of any definite successes or
+failures of previous or subsequent stacked modules this module will
+determine the nature of the response to the application. One example
+of this latter case, is when the other modules return something like
+<tt/PAM_IGNORE/.
</itemize>
@@ -392,12 +506,12 @@ Here, <tt/valueI/ is one of the following <em/return values/:
<tt/authtok_disable_aging/; <tt/try_again/; <tt/ignore/; <tt/abort/;
<tt/authtok_expired/; <tt/module_unknown/; <tt/bad_item/; and
<tt/default/. The last of these (<tt/default/) can be used to set the
-action for those return values that are not set explicitly.
+action for those return values that are not explicitly defined.
<p>
The <tt/actionI/ can be a positive integer or one of the following
tokens: <tt/ignore/; <tt/ok/; <tt/done/; <tt/bad/; <tt/die/; and
-<tt/reset/. A positive integer, <tt/J/, when specified as the action
+<tt/reset/. A positive integer, <tt/J/, when specified as the action,
can be used to indicate that the next <em/J/ modules of the current
type will be skipped. In this way, the administrator can develop a
moderately sophisticated stack of modules with a number of different
@@ -405,9 +519,41 @@ paths of execution. Which path is taken can be determined by the
reactions of individual modules.
<p>
-<bf>Note, at time of writing, this newer syntax is so new that I don't
-want to write too much about it. Please play with this. Report all
-the bugs and make suggestions for new actions (etc.).</bf>
+<itemize>
+<item><tt/ignore/ - when used with a stack of modules, the module's
+ return status will not contribute to the return code the application
+ obtains.
+<item><tt/bad/ - this action indicates that the return code should be
+ thought of as indicative of the module failing. If this module is
+ the first in the stack to fail, its status value will be used for
+ that of the whole stack.
+<item><tt/die/ - equivalent to <tt/bad/ with the side effect of
+ terminating the module stack and PAM immediately returning to the
+ application.
+<item><tt/ok/ - this tells <bf/PAM/ that the administrator thinks this
+ return code should contribute directly to the return code of the full
+ stack of modules. In other words, if the former state of the stack
+ would lead to a return of <tt/PAM_SUCCESS/, the module's return code
+ will override this value. Note, if the former state of the stack
+ holds some value that is indicative of a modules failure, this 'ok'
+ value will not be used to override that value.
+<item><tt/done/ - equivalent to <tt/ok/ with the side effect of
+ terminating the module stack and PAM immediately returning to the
+ application.
+<item><tt/reset/ - clear all memory of the state of the module stack and
+ start again with the next stacked module.
+</itemize>
+
+<p>
+Just to get a feel for the power of this new syntax, here is a taste
+of what you can do with it. With <bf/Linux-PAM-0.63/, the notion of
+client plug-in agents was introduced. This is something that makes it
+possible for PAM to support machine-machine authentication using the
+transport protocol inherent to the client/server application. With
+the ``<tt/[ ... value=action ... ]/'' control syntax, it is possible
+for an application to be configured to support binary prompts with
+compliant clients, but to gracefully fall over into an alternative
+authentication mode for older, legacy, applications. Flexible eh?
<tag> <tt/module-path/</tag>
@@ -431,7 +577,7 @@ next section.
</descrip>
<p>
-Any line in (one of) the confiuration file(s), that is not formatted
+Any line in (one of) the configuration file(s), that is not formatted
correctly, will generally tend (erring on the side of caution) to make
the authentication process fail. A corresponding error is written to
the system log files with a call to <tt/syslog(3)/.
@@ -453,10 +599,10 @@ configuration but not both. That is to say, if there is a
<tt>/etc/pam.d/</tt> directory then libpam only uses the files
contained in this directory. However, in the absence of the
<tt>/etc/pam.d/</tt> directory the <tt>/etc/pam.conf</tt> file is
-used. The other mode (and the one currently supported by Red Hat 4.2)
-is to use both <tt>/etc/pam.d/</tt> and <tt>/etc/pam.conf</tt> in
-sequence. In this mode, entries in <tt>/etc/pam.d/</tt> override
-those of <tt>/etc/pam.conf</tt>.
+used. The other mode (and the one currently supported by Red Hat 4.2
+and higher) is to use both <tt>/etc/pam.d/</tt> and
+<tt>/etc/pam.conf</tt> in sequence. In this mode, entries in
+<tt>/etc/pam.d/</tt> override those of <tt>/etc/pam.conf</tt>.
The syntax of each file in <tt>/etc/pam.d/</tt> is similar to that of
the <tt>/etc/pam.conf</tt> file and is made up of lines of the
@@ -560,6 +706,20 @@ requires some reliably strong encryption to make it secure.
This argument is intended for the <tt/auth/ and <tt/password/ module
types only.
+<tag><tt/expose_account/</tag>
+
+<p>
+In general the leakage of some information about user accounts is not
+a secure policy for modules to adopt. Sometimes information such as
+users names or home directories, or preferred shell, can be used to
+attack a user's account. In some circumstances, however, this sort of
+information is not deemed a threat: displaying a user's full name when
+asking them for a password in a secured environment could also be
+called being 'friendly'. The <tt/expose_account/ argument is a
+standard module argument to encourage a module to be less discrete
+about account information as it is deemed appropriate by the local
+administrator.
+
</descrip>
<sect1>Example configuration file entries
@@ -681,17 +841,6 @@ module-argument, this instructs the UNIX authentication module that it
is not to prompt for a password but rely one already having been
obtained by the ftp module.
-<p>
-The standard UNIX modules, used above, are strongly tied to using the
-default `<tt/libc/' user database functions (see for example, <tt/man
-getpwent/). It is the opinion of the author that these functions are
-not sufficently flexible to make full use of the power of
-<bf/Linux-PAM/. For this reason, and as a small plug, I mention in
-passing that there is a pluggable replacement for the <tt/pam_unix_../
-modules; <tt/pam_pwdb/. See the section below for a more complete
-description.
-
-
<sect>Security issues of Linux-PAM
<p>
@@ -801,6 +950,28 @@ 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.
+<p>
+Here is a sample "other" configuration file. The <em/pam_deny/ module will
+deny access and the <em/pam_warn/ module will send a syslog message to
+<tt/auth.notice/:
+
+<p>
+<tscreen>
+<verb>
+#
+# The PAM configuration file for the `other' service
+#
+auth required pam_deny.so
+auth required pam_warn.so
+account required pam_deny.so
+account required pam_warn.so
+password required pam_deny.so
+password required pam_warn.so
+session required pam_deny.so
+session required pam_warn.so
+</verb>
+</tscreen>
+
<sect>A reference guide for available modules
<p>
@@ -847,8 +1018,8 @@ files; the modules.
PLUGGABLE AUTHENTICATION MODULES'', Open Software Foundation Request
For Comments 86.0, October 1995. See this url:
<tt><htmlurl
-url="http://www.pilgrim.umass.edu/pub/osf_dce/RFC/rfc86.0.txt"
-name="http://www.pilgrim.umass.edu/pub/osf&lowbar;dce/RFC/rfc86.0.txt"></tt>
+url="http://www.kernel.org/pub/linux/libs/pam/pre/doc/rfc86.0.txt.gz"
+name="http://www.kernel.org/pub/linux/libs/pam/pre/doc/rfc86.0.txt.gz"></tt>
</itemize>
@@ -875,37 +1046,9 @@ and in such a way that they need not be distributed with Linux-PAM.
<sect>Author/acknowledgments
<p>
-This document was written by Andrew G. Morgan (morgan@parc.power.net)
+This document was written by Andrew G. Morgan (morgan@kernel.org)
with many contributions from
-<!-- insert credits here -->
-<!--
- an sgml list of people to credit for their contributions to Linux-PAM
- $Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $
- -->
-Craig S. Bell,
-Derrick J. Brashear,
-Ben Buxton,
-Oliver Crow,
-Marc Ewing,
-Cristian Gafton,
-Eric Hester,
-Eric Jacksch,
-Michael K. Johnson,
-David Kinchlea,
-Elliot Lee,
-Al Longyear,
-Marek Michalkiewicz,
-Aleph One,
-Sean Reifschneider,
-Eric Troan,
-Theodore Ts'o,
-Jeff Uphoff,
-Ronald Wahl,
-John Wilmes,
-Joseph S. D. Yao
-and
-Alex O. Yuriev.
-
+<!-- insert-file CREDITS -->
<p>
Thanks are also due to Sun Microsystems, especially to Vipin Samar and
@@ -921,18 +1064,15 @@ More PAM modules are being developed all the time. It is unlikely that
this document will ever be truely up to date!
<p>
-Currently there is no documentation for PAM-aware applications.
-
-<p>
This manual is unfinished. Only a partial list of people is credited
for all the good work they have done.
<sect>Copyright information for this document
<p>
-Copyright (c) Andrew G. Morgan 1996. All rights reserved.
+Copyright (c) Andrew G. Morgan 1996-9. All rights reserved.
<newline>
-Email: <tt>&lt;morgan@parc.power.net&gt;</tt>
+Email: <tt>&lt;morgan@linux.kernel.org&gt;</tt>
<p>
Redistribution and use in source and binary forms, with or without
@@ -980,6 +1120,6 @@ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
<p>
-<tt>$Id: pam_source.sgml,v 1.5 1997/04/05 06:49:14 morgan Exp morgan $</tt>
+<tt>$Id: pam_source.sgml,v 1.5 2001/03/19 01:46:41 agmorgan Exp $</tt>
</article>
diff --git a/contrib/libpam/doc/ps/README b/contrib/libpam/doc/ps/README
index 6234e14f8f8e..5b24f9b52b3a 100644
--- a/contrib/libpam/doc/ps/README
+++ b/contrib/libpam/doc/ps/README
@@ -1,3 +1,3 @@
-$Id: README,v 1.1 1996/11/10 19:28:16 morgan Exp $
+$Id: README,v 1.1.1.1 2000/06/20 22:11:05 agmorgan Exp $
this is the directory for the postscipt documentation
diff --git a/contrib/libpam/doc/specs/draft-morgan-pam.raw b/contrib/libpam/doc/specs/draft-morgan-pam.raw
new file mode 100644
index 000000000000..dec3e566721d
--- /dev/null
+++ b/contrib/libpam/doc/specs/draft-morgan-pam.raw
@@ -0,0 +1,702 @@
+PAM working group ## A.G. Morgan
+Internet Draft: ## October 6, 1999
+Document: draft-morgan-pam-07.txt ##
+Expires: June 13, 2000 ##
+Obsoletes: draft-morgan-pam-06.txt##
+
+## Pluggable Authentication Modules ##
+
+#$ Status of this memo
+
+This document is an draft specification. The latest version of this
+draft may be obtained from here:
+
+ http://linux.kernel.org/pub/linux/libs/pam/pre/doc/
+
+As
+
+ Linux-PAM-'version'-docs.tar.gz
+
+It is also contained in the Linux-PAM tar ball.
+
+#$ Abstract
+
+This document is concerned with the definition of a general
+infrastructure for module based authentication. The infrastructure is
+named Pluggable Authentication Modules (PAM for short).
+
+#$ Introduction
+
+Computers are tools. They provide services to people and other
+computers (collectively we shall call these _users_ entities). In
+order to provide convenient, reliable and individual service to
+different entities, it is common for entities to be labelled. Having
+defined a label as referring to a some specific entity, the label is
+used for the purpose of protecting and allocating data resources.
+
+All modern operating systems have a notion of labelled entities and
+all modern operating systems face a common problem: how to
+authenticate the association of a predefined label with applicant
+entities.
+
+There are as many authentication methods as one might care to count.
+None of them are perfect and none of them are invulnerable. In
+general, any given authentication method becomes weaker over time. It
+is common then for new authentication methods to be developed in
+response to newly discovered weaknesses in the old authentication
+methods.
+
+The problem with inventing new authentication methods is the fact that
+old applications do not support them. This contributes to an inertia
+that discourages the overhaul of weakly protected systems. Another
+problem is that individuals (people) are frequently powerless to layer
+the protective authentication around their systems. They are forced
+to rely on single (lowest common denominator) authentication schemes
+even in situations where this is far from appropriate.
+
+PAM, as discussed in this document, is a generalization of the
+approach first introduced in [#$R#{OSF_RFC_PAM}]. In short, it is a
+general framework of interfaces that abstract the process of
+authentication. With PAM, a service provider can custom protect
+individual services to the level that they deem is appropriate.
+
+PAM has nothing explicit to say about transport layer encryption.
+Within the context of this document encryption and/or compression of
+data exchanges are application specific (strictly between client and
+server) and orthogonal to the process of authentication.
+
+#$ Definitions
+
+Here we pose the authentication problem as one of configuring defined
+interfaces between two entities.
+
+#$$#{players} Players in the authentication process
+
+PAM reserves the following words to specify unique entities in the
+authentication process:
+
+ applicant
+ the entity (user) initiating an application for service
+ [PAM associates the PAM_RUSER _item_ with this requesting user].
+
+ arbitrator
+ the entity (user) under whose identity the service application
+ is negotiated and with whose authority service is granted.
+
+ user
+ the entity (user) whose identity is being authenticated
+ [PAM associates the PAM_USER _item_ with this identity].
+
+ server
+ the application that provides service, or acts as an
+ authenticated gateway to the requested service. This
+ application is completely responsible for the server end of
+ the transport layer connecting the server to the client.
+ PAM makes no assumptions about how data is encapsulated for
+ exchanges between the server and the client, only that full
+ octet sequences can be freely exchanged without corruption.
+
+ client
+ application providing the direct/primary interface to
+ applicant. This application is completely responsible
+ for the client end of the transport layer connecting the
+ server to the client. PAM makes no assumptions about how data
+ is encapsulated for exchanges between the server and the
+ client, only that full octet sequences can be freely
+ exchanged without corruption.
+
+ module
+ authentication binary that provides server-side support for
+ some (arbitrary) authentication method.
+
+ agent
+ authentication binary that provides client-side support for
+ some (arbitrary) authentication method.
+
+Here is a diagram to help orient the reader:
+
+## +-------+ +--------+ ##
+## . . . . .| agent | .| module | ##
+## . +-------+ .+--------+ ##
+## V | . | ##
+## . | V | ##
+## +---------+ +-------+ . +------+ ##
+## | | |libpamc| . |libpam| ##
+## | | +-------+ . +------+ ##
+## |applicant| | . | ##
+## | | +--------+ +----------+ ##
+## | |---| client |-----------| server | ##
+## +---------+ +--------+ +----------+ ##
+
+Solid lines connecting the boxes represent two-way interaction. The
+dotted-directed lines indicate an optional connection beteween the
+plugin module (agent) and the server (applicant). In the case of the
+module, this represents the module invoking the 'conversation'
+callback function provided to libpam by the server application when it
+inititializes the libpam library. In the case of the agent, this may
+be some out-of-PAM API interaction (for example directly displaying a
+dialog box under X).
+
+#$$ Defined Data Types
+
+In this draft, we define two composite data types, the text string and
+the binary prompt. They are the data types used to communicate
+authentication requests and responses.
+
+#$$$#{text_string} text string
+
+The text string is a simple sequence of non-NUL (NUL = 0x00)
+octets. Terminated with a single NUL (0x00) octet. The character set
+employed in the octet sequence may be negotiated out of band, but
+defaults to utf-8.
+
+## --------------------------- ##
+## [ character data | NUL ] ##
+## [ octet sequence | 0x00 ] ##
+## --------------------------- ##
+
+Within the rest of this text, PAM text strings are delimited with a
+pair of double quotes. Example, "this" = {'t';'h';'i';'s';0x00}.
+
+#$$$#{binary_prompt} binary prompt
+
+A binary prompt consists of a stream of octets arranged as follows:
+
+## ---------------------------------------- ##
+## [ u32 | u8 | (length-5 octets) ] ##
+## [ length | control | data ] ##
+## ---------------------------------------- ##
+
+That is, a 32-bit unsigned integer in network byte order, a single
+unsigned byte of control information and a sequence of octets of
+length (length-5). The composition of the _data_ is context dependent
+but is generally not a concern for either the server or the client. It
+is very much the concern of modules and agents.
+
+For purposes of interoperability, we define the following control
+characters as legal.
+
+## value symbol description ##
+## ------------------------------------------------- ##
+## 0x01 PAM_BPC_OK - continuation packet ##
+## 0x02 PAM_BPC_SELECT - initialization packet ##
+## 0x03 PAM_BPC_DONE - termination packet ##
+## 0x04 PAM_BPC_FAIL - unable to execute ##
+
+The following control characters are only legal for exchanges between
+an agent and a client (it is the responsibility of the client to
+enforce this rule in the face of a rogue server):
+
+## 0x41 PAM_BPC_GETENV - obtain client env.var ##
+## 0x42 PAM_BPC_PUTENV - set client env.var ##
+## 0x43 PAM_BPC_TEXT - display message ##
+## 0x44 PAM_BPC_ERROR - display error message ##
+## 0x45 PAM_BPC_PROMPT - echo'd text prompt ##
+## 0x46 PAM_BPC_PASS - non-echo'd text prompt##
+
+Note, length is always equal to the total length of the binary
+prompt and represented by a network ordered unsigned 32 bit integer.
+
+#$$$$#{agent_ids} PAM_BPC_SELECT binary prompts
+
+Binary prompts of control type PAM_BPC_SELECT have a defined
+data part. It is composed of three elements:
+
+ {agent_id;'/';data}
+
+The agent_id is a sequence of characters satisfying the following
+regexp:
+
+ /^[a-z0-9\_]+(@[a-z0-9\_.]+)?$/
+
+and has a specific form for each independent agent.
+
+o Agent_ids that do not contain an at-sign (@) are reserved to be
+ assigned by IANA (Internet Assigned Numbers Authority). Names of
+ this format MUST NOT be used without first registering with IANA.
+ Registered names MUST NOT contain an at-sign (@).
+
+o Anyone can define additional agents by using names in the format
+ name@domainname, e.g. "ouragent@example.com". The part following
+ the at-sign MUST be a valid fully qualified internet domain name
+ [RFC-1034] controlled by the person or organization defining the
+ name. (Said another way, if you control the email address that
+ your agent has as an identifier, they you are entitled to use
+ this identifier.) It is up to each domain how it manages its local
+ namespace.
+
+The '/' character is a mandatory delimiter, indicating the end of the
+agent_id. The trailing data is of a format specific to the agent with
+the given agent_id.
+
+
+#$$ Special cases
+
+In a previous section (#{players}) we identified the most general
+selection of authentication participants. In the case of network
+authentication, it is straightforward to ascribe identities to the
+defined participants. However, there are also special (less general)
+cases that we recognize here.
+
+The primary authentication step, when a user is directly introduced
+into a computer system (log's on to a workstation) is a special case.
+In this situation, the client and the server are generally one
+application. Before authenticating such a user, the applicant is
+formally unknown: PAM_RUSER is NULL.
+
+Some client-server implementations (telnet for example) provide
+effective full tty connections. In these cases, the four simple text
+string prompting cases (see below) can be handled as in the primary
+login step. In other words, the server absorbs most of the overhead of
+propagating authentication messages. In these cases, there is special
+client/server support for handling binary prompts.
+
+#$ Defined interfaces for information flow
+
+Here, we discuss the information exchange interfaces between the
+players in the authentication process. It should be understood that
+the server side is responsible for driving the authentication of the
+applicant. Notably, every request received by the client from the
+server must be matched with a single response from the client to the
+server.
+
+#$$#{applicant_client} Applicant <-> client
+
+Once the client is invoked, requests to the applicant entity are
+initiated by the client application. General clients are able to make
+the following requests directly to an applicant:
+
+ echo text string
+ echo error text string
+ prompt with text string for echo'd text string input
+ prompt with text string for concealed text string input
+
+the nature of the interface provided by the client for the benefit of
+the applicant entity is client specific and not defined by PAM.
+
+#$$#{client_agent} Client <-> agent
+
+In general, authentication schemes require more modes of exchange than
+the four defined in the previous section (#{applicant_client}). This
+provides a role for client-loadable agents. The client and agent
+exchange binary-messages that can have one of the following forms:
+
+ client -> agent
+ binary prompt agent expecting binary prompt reply to client
+
+ agent -> client
+ binary prompt reply from agent to clients binary prompt
+
+Following the acceptance of a binary prompt by the agent, the agent
+may attempt to exchange information with the client before returning
+its binary prompt reply. Permitted exchanges are binary prompts of the
+following types:
+
+ agent -> client
+ set environment variable (A)
+ get environment variable (B)
+ echo text string (C)
+ echo error text string (D)
+ prompt for echo'd text string input (E)
+ prompt for concealed text string input (F)
+
+In response to these prompts, the client must legitimately respond
+with a corresponding binary prompt reply. We list a complete set of
+example exchanges, including each type of legitimate response (passes
+and a single fail):
+
+## Type | Agent request | Client response ##
+## --------------------------------------------------------------- ##
+## (A) | {13;PAM_BPC_PUTENV;"FOO=BAR"} | {5;PAM_BPC_OK;} ##
+## | {10;PAM_BPC_PUTENV;"FOO="} | {5;PAM_BPC_OK;} ##
+## | {9;PAM_BPC_PUTENV;"FOO"} (*) | {5;PAM_BPC_OK;} ##
+## | {9;PAM_BPC_PUTENV;"BAR"} (*) | {5;PAM_BPC_FAIL;} ##
+## --------------------------------------------------------------- ##
+## (B) | {10;PAM_BPC_GETENV;"TERM"} | {11;PAM_BPC_OK;"vt100"} ##
+## | {9;PAM_BPC_GETENV;"FOO"} | {5;PAM_BPC_FAIL;} ##
+## --------------------------------------------------------------- ##
+## (C) | {12;PAM_BPC_TEXT;"hello!"} | {5;PAM_BPC_OK;} ##
+## | {12;PAM_BPC_TEXT;"hello!"} | {5;PAM_BPC_FAIL;} ##
+## --------------------------------------------------------------- ##
+## (D) | {11;PAM_BPC_TEXT;"ouch!"} | {5;PAM_BPC_OK;} ##
+## | {11;PAM_BPC_TEXT;"ouch!"} | {5;PAM_BPC_FAIL;} ##
+## --------------------------------------------------------------- ##
+## (E) | {13;PAM_BPC_PROMPT;"login: "} | {9;PAM_BPC_OK;"joe"} ##
+## | {13;PAM_BPC_PROMPT;"login: "} | {6;PAM_BPC_OK;""} ##
+## | {13;PAM_BPC_PROMPT;"login: "} | {5;PAM_BPC_FAIL;} ##
+## --------------------------------------------------------------- ##
+## (F) | {16;PAM_BPC_PASS;"password: "} | {9;PAM_BPC_OK;"XYZ"} ##
+## | {16;PAM_BPC_PASS;"password: "} | {6;PAM_BPC_OK;""} ##
+## | {16;PAM_BPC_PASS;"password: "} | {5;PAM_BPC_FAIL;} ##
+
+(*) Used to attempt the removal of a pre-existing environment
+variable.
+
+#$$ Client <-> server
+
+Once the client has established a connection with the server (the
+nature of the transport protocol is not specified by PAM), the server
+is responsible for driving the authentication process.
+
+General servers can request the following from the client:
+
+ (to be forwarded by the client to the applicant)
+ echo text string
+ echo error text string
+ prompt for echo'd text string response
+ prompt for concealed text string response
+
+ (to be forwarded by the client to the appropriate agent)
+ binary prompt for a binary prompt response
+
+Client side agents are required to process binary prompts. The
+agents' binary prompt responses are returned to the server.
+
+#$$ Server <-> module
+
+Modules drive the authentication process. The server provides a
+conversation function with which it encapsulates module-generated
+requests and exchanges them with the client. Every message sent by a
+module should be acknowledged.
+
+General conversation functions can support the following five
+conversation requests:
+
+ echo text string
+ echo error string
+ prompt for echo'd text string response
+ prompt for concealed text string response
+ binary prompt for binary prompt response
+
+The server is responsible for redirecting these requests to the
+client.
+
+#$ C API for application interfaces (client and server)
+
+#$$ Applicant <-> client
+
+No API is defined for this interface. The interface is considered to
+be specific to the client application. Example applications include
+terminal login, (X)windows login, machine file transfer applications.
+
+All that is important is that the client application is able to
+present the applicant with textual output and to receive textual
+input from the applicant. The forms of textual exchange are listed
+in an earlier section (#{applicant_client}). Other methods of
+data input/output are better suited to being handled via an
+authentication agent.
+
+#$$ Client <-> agent
+
+The client makes use of a general API for communicating with
+agents. The client is not required to communicate directly with
+available agents, instead a layer of abstraction (in the form of a
+library: libpamc) takes care of loading and maintaining communication
+with all requested agents. This layer of abstraction will choose which
+agents to interact with based on the content of binary prompts it
+receives that have the control type PAM_BPC_SELECT.
+
+#$$$ Client <-> libpamc
+
+#$$$$ Compilation information
+
+The C-header file provided for client-agent abstraction is included
+with the following source line:
+
+ \#include <security/pam_client.h>
+
+The library providing the corresponding client-agent abstraction
+functions is, libpamc.
+
+ cc .... -lpamc
+
+#$$$$ Initializing libpamc
+
+The libpamc library is initialized with a call to the following
+function:
+
+ pamc_handle_t pamc_start(void);
+
+This function is responsible for configuring the library and
+registering the location of available agents. The location of the
+available agents on the system is implementation specific.
+
+pamc_start() function returns NULL on failure. Otherwise, the return
+value is a pointer to an opaque data type which provides a handle to
+the libpamc library. On systems where threading is available, the
+libpamc libraray is thread safe provided a single (pamc_handler_t *)
+is used by each thread.
+
+#$$$$ Client (Applicant) selection of agents
+
+For the purpose of applicant and client review of available agents,
+the following function is provided.
+
+ char **pamc_list_agents(pamc_handle_t pch);
+
+This returns a list of pointers to the agent_id's of the agents which
+are available on the system. The list is terminated by a NULL pointer.
+It is the clients responsibility to free this memory area by calling
+free() on each agent id and the block of agent_id pointers in the
+result.
+
+PAM represents a server-driven authentication model, so by default
+any available agent may be invoked in the authentication process.
+
+#$$$$$ Client demands agent
+
+If the client requires that a specific authentication agent is
+satisfied during the authentication process, then the client should
+call the following function, immediately after obtaining a
+pamc_handle_t from pamc_start().
+
+ int pamc_load(pamc_handle_t pch, const char *agent_id);
+
+agent_id is a PAM text string (see section #{agent_ids}) and is not
+suffixed with a '/' delimiter. The return value for this function is:
+
+ PAM_BPC_TRUE - agent located and loaded.
+ PAM_BPC_FALSE - agent is not available.
+
+Note, although the agent is loaded, no data is fed to it. The agent's
+opportunity to inform the client that it does not trust the server is
+when the agent is shutdown.
+
+#$$$$$ Client marks agent as unusable
+
+The applicant might prefer that a named agent is marked as not
+available. To do this, the client would invoke the following function
+immediately after obtaining a pamc_handle_t from pam_start().
+
+ int pamc_disable(pamc_handle_t pch, const char *agent_id);
+
+here agent_id is a PAM text string containing an agent_id (section
+#{agent_ids}).
+
+The return value for this function is:
+
+ PAM_BPC_TRUE - agent is disabled. This is the response
+ independent of whether the agent is locally
+ available.
+
+ PAM_BPC_FALSE - agent cannot be disabled (this may be because
+ it has already been invoked).
+
+#$$$$ Allocating and manipulating binary prompts
+
+All conversation between an client and an agent takes place with
+respect to binary prompts. A binary prompt (see section #{binary_prompt}), is
+obtained, resized and deleted via the following C-macro:
+
+ CREATION of a binary prompt with control X1 and data length Y1:
+
+ pamc_bp_t prompt = NULL;
+ PAM_BP_RENEW(&prompt, X1, Y1);
+
+ REPLACEMENT of a binary prompt with a control X2 and data length Y2:
+
+ PAM_BP_RENEW(&prompt, X2, Y2);
+
+ DELETION of a binary prompt (the referenced prompt is scrubbed):
+
+ PAM_BP_RENEW(&prompt, 0, 0);
+
+Note, the PAM_BP_RENEW macro always overwrites any prompt that you
+call it with, deleting and liberating the old contents in a secure
+fashion. Also note that PAM_BP_RENEW, when returning a prompt of data
+size Y1>0, will always append a '\0' byte to the end of the prompt (at
+data offset Y1). It is thus, by definition, acceptable to treat the
+data contents of a binary packet as a text string (see #{text_string}).
+
+ FILLING a binary prompt from a memory pointer U1 from offset O1 of
+ length L1:
+
+ PAM_BP_FILL(prompt, O1, L1, U1);
+
+ the CONTROL type for the packet can be obtained as follows:
+
+ control = PAM_PB_CONTROL(prompt);
+
+ the LENGTH of a data within the prompt (_excluding_ its header
+ information) can be obtained as follows:
+
+ length = PAM_BP_LENGTH(prompt);
+
+ the total SIZE of the prompt (_including_ its header information)
+ can be obtained as follows:
+
+ size = PAM_BP_SIZE(prompt);
+
+ EXTRACTING data from a binary prompt from offset O2 of length L2 to
+ a memory pointer U2:
+
+ PAM_BP_EXTRACT(prompt, O2, L2, U2);
+
+ If you require direct access to the raw prompt DATA, you should use
+ the following macro:
+
+ __u8 *raw_data = PAM_BP_DATA(prompt);
+
+#$$$$ Client<->agent conversations
+
+All exchanges of binary prompts with agents are handled with the
+single function:
+
+ int pamc_converse(pamc_handle_t *pch, pamc_bp_t *prompt_p);
+
+The return value for pamc_converse(...) is PAM_BPC_TRUE when there is
+a response packet and PAM_BPC_FALSE when the client is unable to
+handle the request represented by the original prompt. In this latter
+case, *prompt_p is set to NULL.
+
+This function takes a binary prompt and returns a replacement binary
+prompt that is either a request from an agent to be acted upon by the
+client or the 'result' which should be forwarded to the server. In the
+former case, the following macro will return 1 (PAM_BPC_TRUE) and in
+all other cases, 0 (PAM_BPC_FALSE):
+
+ PAM_BPC_FOR_CLIENT(/* pamc_bp_t */ prompt)
+
+Note, all non-NULL binary prompts returned by pamc_converse(...), are
+terminated with a '\0', even when the full length of the prompt (as
+returned by the agent) does not contain this delimiter. This is a
+defined property of the PAM_BP_RENEW macro, and can be relied upon.
+
+Important security note: in certain implementations, agents are
+implemented by executable binaries, which are transparently loaded and
+managed by the PAM client library. To ensure there is never a leakage
+of elevated privilege to an unprivileged agent, the client application
+should go to some effort to lower its level of privilege. It remains
+the responsibility of the applicant and the client to ensure that it
+is not compromised by a rogue agent.
+
+#$$$$ Termination of agents
+
+When closing the authentication session and severing the connection
+between a client and a selection of agents, the following function is
+used:
+
+ int pamc_end(pamc_handle_t *pch);
+
+Following a call to pamc_end, the pamc_handle_t will be invalid.
+
+The return value for this function is one of the following:
+
+ PAM_BPC_TRUE - all invoked agents are content with
+ authentication (the server is _not_ judged
+ _un_trustworthy by any agent)
+
+ PAM_BPC_FALSE - one or more agents were unsatisfied at
+ being terminated. In general, the client
+ should terminate its connection to the
+ server and indicate to the applicant that
+ the server is untrusted.
+
+#$$$ libpamc <-> agents
+
+The agents are manipulated from within libpamc. Each agent is an
+executable in its own right. This permits the agent to have access to
+sensitive data not accessible directly from the client. The mode of
+communication between libpamc and an agent is through a pair of
+pipes. The agent reads binary prompts (section #{binary_prompt})
+through its standard input file descriptor and writes response (to the
+server) binary prompts and instruction binary prompts (instructions
+for the client) through its standard output file descriptor.
+
+#$$ Client <-> server
+
+This interface is concerned with the exchange of text and binary
+prompts between the client application and the server application. No
+API is provided for this as it is considered specific to the transport
+protocol shared by the client and the server.
+
+#$$ Server <-> modules
+
+The server makes use of a general API for communicating with
+modules. The client is not required to communicate directly with
+available modules. By abstracting the authentication interface, it
+becomes possible for the local administrator to make a run time
+decision about the authentication method adopted by the server.
+
+#$$$ Functions and definitions available to servers and modules
+
+[This section will document the following functions
+
+ pam_set_item()
+ pam_get_item()
+ pam_fail_delay(pam_handle_t *pamh, unsigned int micro_sec)
+ pam_get_env(pam_handle_t *pamh, const char *varname)
+ pam_strerror(pam_handle_t *pamh, int pam_errno)
+]
+
+#$$$ Server <-> libpam
+
+[This section will document the following pam_ calls:
+
+ pam_start
+ pam_end
+ pam_authenticate (*)
+ pam_setcred
+ pam_acct_mgmt
+ pam_open_session
+ pam_close_session
+ pam_chauthtok (*)
+
+The asterisked functions may return PAM_INCOMPLETE. In such cases, the
+application should be aware that the conversation function was called
+and that it returned PAM_CONV_AGAIN to a module. The correct action
+for the application to take in response to receiving PAM_INCOMPLETE,
+is to acquire the replies so that the next time the conversation
+function is called it will be able to provide the desired
+responses. And then recall pam_authenticate (pam_chauthtok) with the
+same arguments. Libpam will arrange that the module stack is resumed
+from the module that returned before. This functionality is required
+for programs whose user interface is maintained by an event loop. ]
+
+#$$$ libpam <-> modules
+
+[This section will document the following pam_ and pam_sm_ calls:
+
+functions provided by libpam
+
+ pam_set_data
+ pam_get_data
+
+functions provided to libpam by each module
+
+ groups:
+ AUTHENTICATION
+ pam_sm_authenticate
+ pam_sm_setcred
+ ACCOUNT
+ pam_sm_acct_mgmt
+ SESSION
+ pam_sm_open_session
+ pam_sm_close_session
+ AUTHENTICATION TOKEN MANAGEMENT
+ pam_sm_chauthtok
+]
+
+#$ Security considerations
+
+This document is devoted to standardizing authentication
+infrastructure: everything in this document has implications for
+security.
+
+#$ Contact
+
+The email list for discussing issues related to this document is
+<pam-list@redhat.com>.
+
+#$ References
+
+[#{OSF_RFC_PAM}] OSF RFC 86.0, "Unified Login with Pluggable Authentication
+ Modules (PAM)", October 1995
+
+#$ Author's Address
+
+Andrew G. Morgan
+Email: morgan@ftp.kernel.org
+
+## $Id: draft-morgan-pam.raw,v 1.1.1.1 2000/06/20 22:11:07 agmorgan Exp $ ##
+
diff --git a/contrib/libpam/doc/txts/README b/contrib/libpam/doc/txts/README
index b62bc2d7448a..f63820cffde0 100644
--- a/contrib/libpam/doc/txts/README
+++ b/contrib/libpam/doc/txts/README
@@ -1,3 +1,3 @@
-$Id: README,v 1.1 1996/11/10 19:18:06 morgan Exp $
+$Id: README,v 1.1.1.1 2000/06/20 22:11:12 agmorgan Exp $
This is a directory for text versions of the pam documentation
diff --git a/contrib/libpam/examples/Makefile b/contrib/libpam/examples/Makefile
index 063f24d0df03..2cf67f7007aa 100644
--- a/contrib/libpam/examples/Makefile
+++ b/contrib/libpam/examples/Makefile
@@ -1,19 +1,30 @@
#
-# $Id: Makefile,v 1.10 1996/11/10 19:50:59 morgan Exp $
+# $Id: Makefile,v 1.4 2001/02/10 07:17:53 agmorgan Exp $
#
-dummy:
-
- @echo "*** This is not a top level Makefile!"
+include ../Make.Rules
PROGS = blank xsh check_user
SRCS = blank.c xsh.c check_user.c
+PROGSUID =
-# have removed the following pair since they no longer conform to
-# any recognized conventions: vpass test
-# ditto: vpass.c test.c
+ifeq ($(WITH_LIBDEBUG),yes)
+ LIBSUFFIX=d
+else
+ LIBSUFFIX=
+endif
-PROGSUID =
+CFLAGS += -I../libpam_misc/include -I../libpamc/include
+
+LOADLIBES = -L../libpam -L../libpamc -L../libpam_misc \
+ -lpam$(LIBSUFFIX) -lpam_misc$(LIBSUFFIX)
+
+ifeq ($(STATIC_LIBPAM),yes)
+ ifneq ($(DYNAMIC),)
+ CFLAGS += $(CC_STATIC)
+ LOADLIBES += $(LIBDL)
+ endif
+endif
all: $(PROGS)
@@ -26,17 +37,18 @@ blank: blank.o
xsh: xsh.o
$(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
+clean:
+ rm -f *.a *.so *.o *~ $(PROGS) $(PROGSUID)
+ rm -f *.a *.out *.o *.so
+
+# note, the programs are test programs, they should not be
+# installed on your system!
+
install: all
if [ -n "$(PROGS)" ]; then cp $(PROGS) ../bin ; fi
if [ -n "$(PROGSUID)" ]; then \
- $(INSTALL) -m 4555 -o root -g bin $(PROGSUID) ../bin ; fi
-
-clean:
- rm -f *.a *.so *.o *~ $(PROGS) $(PROGSUID)
+ $(INSTALL) -m 4555 $(PROGSUID) ../bin ; fi
remove:
cd ../bin ; rm -f $(PROGS) $(PROGSUID)
-
-extraclean: clean
- rm -f *.a *.out *.o *.so
for x in $(PROGS) $(PROGSUID) ; do rm -f ../bin/$$x ; done
diff --git a/contrib/libpam/examples/blank.c b/contrib/libpam/examples/blank.c
index 3808e5589f80..20896b5ced75 100644
--- a/contrib/libpam/examples/blank.c
+++ b/contrib/libpam/examples/blank.c
@@ -1,20 +1,5 @@
/*
- * $Id: blank.c,v 1.7 1996/12/01 03:16:53 morgan Exp morgan $
- *
- * $Log: blank.c,v $
- * Revision 1.7 1996/12/01 03:16:53 morgan
- * added setcred closing function
- *
- * Revision 1.6 1996/11/10 19:51:40 morgan
- * minor change to avoid gcc warning
- *
- * Revision 1.5 1996/07/07 23:53:05 morgan
- * added optional fail delay (non-standard Linux-PAM)
- *
- * Revision 1.4 1996/05/02 04:44:18 morgan
- * moved conversation to a libmisc library routine.
- *
- *
+ * $Id: blank.c,v 1.2 2000/12/04 19:02:33 baggins Exp $
*/
/* Andrew Morgan (morgan@parc.power.net) -- a self contained `blank'
@@ -53,7 +38,7 @@ static struct pam_conv conv = {
/* ------- the application itself -------- */
-void main(int argc, char **argv)
+int main(int argc, char **argv)
{
pam_handle_t *pamh=NULL;
char *username=NULL;
diff --git a/contrib/libpam/examples/check_user.c b/contrib/libpam/examples/check_user.c
index 6a64c22d7ad9..cb539c4ee998 100644
--- a/contrib/libpam/examples/check_user.c
+++ b/contrib/libpam/examples/check_user.c
@@ -1,5 +1,5 @@
/*
- $Id: check_user.c,v 1.1 1996/11/10 21:19:30 morgan Exp morgan $
+ $Id: check_user.c,v 1.2 2000/12/04 19:02:33 baggins Exp $
This program was contributed by Shane Watts <shane@icarus.bofh.asn.au>
slight modifications by AGM.
@@ -8,12 +8,7 @@
# check authorization
check auth required pam_unix_auth.so
check account required pam_unix_acct.so
-
- $Log: check_user.c,v $
- Revision 1.1 1996/11/10 21:19:30 morgan
- Initial revision
-
- */
+*/
#include <security/pam_appl.h>
#include <security/pam_misc.h>
diff --git a/contrib/libpam/examples/test.c b/contrib/libpam/examples/test.c
index 0a1f5a6168fb..7e166b48ba98 100644
--- a/contrib/libpam/examples/test.c
+++ b/contrib/libpam/examples/test.c
@@ -1,16 +1,5 @@
/*
- * $Log: test.c,v $
- * Revision 1.3 1996/03/10 00:14:20 morgan
- * made lines less than 80 chars long.
- *
- * Revision 1.2 1996/03/09 09:16:26 morgan
- * changed the header file that it includes.
- *
- * Revision 1.1 1996/03/09 09:13:34 morgan
- * Initial revision
- */
-
-/* Marc Ewing (marc@redhat.com) - original test code
+ * Marc Ewing (marc@redhat.com) - original test code
* Alexander O. Yuriev (alex@bach.cis.temple.edu)
* Andrew Morgan (morgan@physics.ucla.edu)
*/
diff --git a/contrib/libpam/examples/vpass.c b/contrib/libpam/examples/vpass.c
index 617a5f2e8241..9a07ee380340 100644
--- a/contrib/libpam/examples/vpass.c
+++ b/contrib/libpam/examples/vpass.c
@@ -36,7 +36,7 @@ int main(void)
pam_start("vpass", user, &conv, &pamh);
pam_set_item(pamh, PAM_TTY, "/dev/tty");
if ((res = pam_authenticate(pamh, 0)) != PAM_SUCCESS) {
- fprintf(stderr, "Oops: %s\n", pam_strerror(res));
+ fprintf(stderr, "Oops: %s\n", pam_strerror(pamh, res));
exit(1);
}
diff --git a/contrib/libpam/examples/xsh.c b/contrib/libpam/examples/xsh.c
index ad134f6217ba..ea54886462fe 100644
--- a/contrib/libpam/examples/xsh.c
+++ b/contrib/libpam/examples/xsh.c
@@ -1,22 +1,8 @@
/*
- * $Id: xsh.c,v 1.4 1996/11/10 21:09:45 morgan Exp morgan $
- *
- * $Log: xsh.c,v $
- * Revision 1.4 1996/11/10 21:09:45 morgan
- * no gcc warnings
- *
- * Revision 1.3 1996/07/07 23:53:36 morgan
- * added support for non standard pam_fail_delay
- *
- * Revision 1.2 1996/05/02 04:44:48 morgan
- * moved conversaation to a libmisc routine.
- *
- * Revision 1.1 1996/04/07 08:18:55 morgan
- * Initial revision
- *
+ * $Id: xsh.c,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
*/
-/* Andrew Morgan (morgan@parc.power.net) -- an example application
+/* Andrew Morgan (morgan@kernel.org) -- an example application
* that invokes a shell, based on blank.c */
#include <stdio.h>
@@ -44,22 +30,28 @@ static struct pam_conv conv = {
/* ------- the application itself -------- */
-void main(int argc, char **argv, char **envp)
+int main(int argc, char **argv)
{
pam_handle_t *pamh=NULL;
- char *username=NULL;
+ const char *username=NULL;
+ const char *service="xsh";
int retcode;
- /* did the user call with a username as an argument ? */
+ /* did the user call with a username as an argument ?
+ * did they also */
- if (argc > 2) {
- fprintf(stderr,"usage: %s [username]\n",argv[0]);
- } else if (argc == 2) {
+ if (argc > 3) {
+ fprintf(stderr,"usage: %s [username [service-name]]\n",argv[0]);
+ }
+ if (argc >= 2) {
username = argv[1];
- }
+ }
+ if (argc == 3) {
+ service = argv[2];
+ }
/* initialize the Linux-PAM library */
- retcode = pam_start("xsh", username, &conv, &pamh);
+ retcode = pam_start(service, username, &conv, &pamh);
bail_out(pamh,1,retcode,"pam_start");
/* to avoid using goto we abuse a loop here */
@@ -111,7 +103,10 @@ void main(int argc, char **argv, char **envp)
break;
}
- fprintf(stderr,"The user has been authenticated and `logged in'\n");
+ pam_get_item(pamh, PAM_USER, (const void **) &username);
+ fprintf(stderr,
+ "The user [%s] has been authenticated and `logged in'\n",
+ username);
/* this is always a really bad thing for security! */
system("/bin/sh");
@@ -127,6 +122,15 @@ void main(int argc, char **argv, char **envp)
break;
}
+ /* `0' could be as above */
+ retcode = pam_setcred(pamh, PAM_DELETE_CRED);
+ bail_out(pamh,0,retcode,"pam_setcred");
+ if (retcode != PAM_SUCCESS) {
+ fprintf(stderr,"%s: problem deleting user credentials\n"
+ ,argv[0]);
+ break;
+ }
+
break; /* don't go on for ever! */
}
diff --git a/contrib/libpam/libpam/Makefile b/contrib/libpam/libpam/Makefile
index f3914a478b9a..9d3e6d7391e8 100644
--- a/contrib/libpam/libpam/Makefile
+++ b/contrib/libpam/libpam/Makefile
@@ -1,45 +1,14 @@
#
-# $Id: Makefile,v 1.19 1997/04/05 06:58:43 morgan Exp morgan $
+# $Id: Makefile,v 1.4 2001/02/10 07:17:53 agmorgan Exp $
#
-# $Log: Makefile,v $
-# Revision 1.19 1997/04/05 06:58:43 morgan
-# fakeroot
-#
-# Revision 1.18 1997/02/15 15:56:09 morgan
-# inherit major and minor numbers
-#
-# Revision 1.17 1997/01/04 20:03:09 morgan
-# update for .55
-#
-# Revision 1.16 1996/12/01 03:14:13 morgan
-# update for .54
-#
-# Revision 1.15 1996/11/10 20:07:51 morgan
-# updated for .53
-#
-# Revision 1.14 1996/09/05 06:06:53 morgan
-# added local flag for locking, slight reorganization too.
#
+include ../Make.Rules
+
# need to tell libpam about the default directory for PAMs
MOREFLAGS=-D"DEFAULT_MODULE_PATH=\"$(SECUREDIR)/\""
-# you may uncomment the following to build libpam in modified ways
-
-# lots of debugging information goes to /tmp/pam-debug.log
-#MOREFLAGS += -D"DEBUG"
-
-# pay attention to locked /etc/pam.conf or /etc/pam.d/* files
-#MOREFLAGS += -D"PAM_LOCKING"
-
-# read both the /etc/pam.d/ and pam.conf files specific to the deisred service
-#MOREFLAGS += -D"PAM_READ_BOTH_CONFS"
-
-# make a kludge attempt to be compatible with the old pam_strerror
-# calling convention
-#MOREFLAGS += -D"UGLY_HACK_FOR_PRIOR_BEHAVIOR_SUPPORT"
-
-ifeq ($(DEBUG_REL),yes)
+ifeq ($(WITH_LIBDEBUG),yes)
LIBNAME=libpamd
else
LIBNAME=libpam
@@ -49,12 +18,13 @@ MODIFICATION=.$(MINOR_REL)
# ---------------------------------------------
-dummy:
- @echo "*** This is not a top-level Makefile!"
+dummy: ../Make.Rules all
# ---------------------------------------------
-CFLAGS += $(DYNAMIC) $(STATIC) $(MOREFLAGS)
+CFLAGS += $(DYNAMIC) $(STATIC) $(MOREFLAGS) \
+ -DLIBPAM_VERSION_MAJOR=$(MAJOR_REL) \
+ -DLIBPAM_VERSION_MINOR=$(MINOR_REL)
# dynamic library names
@@ -67,8 +37,11 @@ LIBPAMFULL = $(LIBPAMNAME)$(MODIFICATION)
LIBPAMSTATIC = $(LIBNAME).a
ifdef STATIC
+@echo Did you mean to set STATIC\?
MODULES = $(shell cat ../modules/_static_module_objects)
STATICOBJ = pam_static.o
+else
+MODULES =
endif
ifdef MEMORY_DEBUG
@@ -80,15 +53,16 @@ LIBOBJECTS = pam_item.o pam_strerror.o pam_end.o pam_start.o pam_data.o \
pam_account.o pam_auth.o pam_session.o pam_password.o \
pam_env.o pam_log.o $(EXTRAS)
-ifdef DYNAMIC_LIBPAM
+ifeq ($(DYNAMIC_LIBPAM),yes)
+# libpam.so needs -ldl, too.
DLIBOBJECTS = $(addprefix dynamic/,$(LIBOBJECTS) $(STATICOBJ))
-ifdef STATICOBJ
+ifeq ($(STATICOBJ),yes)
dynamic/pam_static.o: pam_static.c ../modules/_static_module_objects
$(CC) $(CFLAGS) -c pam_static.c -o $@
endif
endif
-ifdef STATIC_LIBPAM
+ifeq ($(STATIC_LIBPAM),yes)
SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS) $(STATICOBJ))
ifdef STATICOBJ
static/pam_static.o: pam_static.c ../modules/_static_module_objects
@@ -99,45 +73,46 @@ endif
# ---------------------------------------------
## rules
-all: dirs $(LIBPAM) $(LIBPAMSTATIC)
+all: dirs $(LIBPAM) $(LIBPAMSTATIC) ../Make.Rules
dirs:
-ifdef DYNAMIC_LIBPAM
- mkdir -p dynamic
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(MKDIR) dynamic
endif
-ifdef STATIC_LIBPAM
- mkdir -p static
+ifeq ($(STATIC_LIBPAM),yes)
+ $(MKDIR) static
endif
dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
$(LIBPAM): $(DLIBOBJECTS)
-ifdef DYNAMIC_LIBPAM
+ifeq ($(DYNAMIC_LIBPAM),yes)
ifeq ($(USESONAME),yes)
- $(LD_L) $(SOSWITCH) $(LIBPAMNAME) -o $@ $(DLIBOBJECTS) $(MODULES)
+ $(LD_L) $(SOSWITCH) $(LIBPAMNAME) -o $@ $(DLIBOBJECTS) \
+ $(MODULES) $(LINKLIBS)
else
- $(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
+ $(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
endif
ifeq ($(NEEDSONAME),yes)
rm -f $(LIBPAMFULL)
- ln -s $(LIBPAM) $(LIBPAMFULL)
+ ln -sf $(LIBPAM) $(LIBPAMFULL)
rm -f $(LIBPAMNAME)
- ln -s $(LIBPAM) $(LIBPAMNAME)
+ ln -sf $(LIBPAM) $(LIBPAMNAME)
endif
endif
$(LIBPAMSTATIC): $(SLIBOBJECTS)
-ifdef STATIC_LIBPAM
- $(AR) $@ $(SLIBOBJECTS) $(MODULES)
+ifeq ($(STATIC_LIBPAM),yes)
+ ar cr $@ $(SLIBOBJECTS) $(MODULES)
$(RANLIB) $@
endif
install: all
- $(MKDIR) $(FAKEROOT)$(INCLUDED)
+ $(MKDIR) $(FAKEROOT)$(INCLUDED) $(FAKEROOT)$(libdir)
$(INSTALL) -m 644 include/security/pam_appl.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/pam_modules.h $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/security/_pam_macros.h $(FAKEROOT)$(INCLUDED)
@@ -146,15 +121,16 @@ install: all
ifdef MEMORY_DEBUG
$(INSTALL) -m 644 include/security/pam_malloc.h $(FAKEROOT)$(INCLUDED)
endif
-ifdef DYNAMIC_LIBPAM
- $(INSTALL) -m $(SHLIBMODE) $(LIBPAM) $(FAKEROOT)$(LIBDIR)/$(LIBPAMFULL)
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(INSTALL) -m $(SHLIBMODE) $(LIBPAM) $(FAKEROOT)$(libdir)/$(LIBPAMFULL)
$(LDCONFIG)
ifneq ($(DYNTYPE),"sl")
- ( cd $(FAKEROOT)$(LIBDIR) ; rm -f $(LIBPAM) ; ln -s $(LIBPAMNAME) $(LIBPAM) )
+ ( cd $(FAKEROOT)$(libdir) ; rm -f $(LIBPAM) ; \
+ ln -sf $(LIBPAMNAME) $(LIBPAM) )
endif
endif
-ifdef STATIC_LIBPAM
- $(INSTALL) -m 644 $(LIBPAMSTATIC) $(FAKEROOT)$(LIBDIR)
+ifeq ($(STATIC_LIBPAM),yes)
+ $(INSTALL) -m 644 $(LIBPAMSTATIC) $(FAKEROOT)$(libdir)
endif
remove:
@@ -163,15 +139,13 @@ remove:
rm -f $(FAKEROOT)$(INCLUDED)/pam_appl.h
rm -f $(FAKEROOT)$(INCLUDED)/pam_modules.h
rm -f $(FAKEROOT)$(INCLUDED)/pam_malloc.h
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAM).*
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAM)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBPAM).*
+ rm -f $(FAKEROOT)$(libdir)/$(LIBPAM)
$(LDCONFIG)
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBPAMSTATIC)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBPAMSTATIC)
clean:
rm -f a.out core *~ static/*.o dynamic/*.o
-
-extraclean: clean
- rm -f *.a *.out *.o *.so ./include/security/*~
+ rm -f *.a *.o *.so ./include/security/*~
if [ -d dynamic ]; then rmdir dynamic ; fi
if [ -d static ]; then rmdir static ; fi
diff --git a/contrib/libpam/libpam/include/security/_pam_compat.h b/contrib/libpam/libpam/include/security/_pam_compat.h
index acfc59231af0..33520a6c64c3 100644
--- a/contrib/libpam/libpam/include/security/_pam_compat.h
+++ b/contrib/libpam/libpam/include/security/_pam_compat.h
@@ -2,7 +2,10 @@
#define _PAM_COMPAT_H
/*
+ * $Id: _pam_compat.h,v 1.1.1.1 2000/06/20 22:11:21 agmorgan Exp $
+ *
* This file was contributed by Derrick J Brashear <shadow@dementia.org>
+ * slight modification by Brad M. Garcia <bgarcia@fore.com>
*
* A number of operating systems have started to implement PAM.
* unfortunately, they have a different set of numeric values for
@@ -12,16 +15,24 @@
/* Solaris uses different constants. We redefine to those here */
#if defined(solaris) || (defined(__SVR4) && defined(sun))
-/* generic for pam_* functions */
-# undef PAM_SILENT
-# define PAM_SILENT 0x80000000
+#ifndef _SECURITY__PAM_TYPES_H
+
+# ifdef _SECURITY_PAM_MODULES_H
/* flags for pam_chauthtok() */
-# undef PAM_PRELIM_CHECK
-# define PAM_PRELIM_CHECK 0x1
+# undef PAM_PRELIM_CHECK
+# define PAM_PRELIM_CHECK 0x1
+
+# undef PAM_UPDATE_AUTHTOK
+# define PAM_UPDATE_AUTHTOK 0x2
+
+# endif /* _SECURITY_PAM_MODULES_H */
-# undef PAM_UPDATE_AUTHTOK
-# define PAM_UPDATE_AUTHTOK 0x2
+#else /* _SECURITY__PAM_TYPES_H */
+
+/* generic for pam_* functions */
+# undef PAM_SILENT
+# define PAM_SILENT 0x80000000
/* flags for pam_setcred() */
# undef PAM_ESTABLISH_CRED
@@ -33,8 +44,8 @@
# undef PAM_REINITIALIZE_CRED
# define PAM_REINITIALIZE_CRED 0x4
-# define PAM_REFRESH_CRED 0x8
# undef PAM_REFRESH_CRED
+# define PAM_REFRESH_CRED 0x8
/* another binary incompatibility comes from the return codes! */
@@ -104,6 +115,8 @@
# undef PAM_TRY_AGAIN
# define PAM_TRY_AGAIN 27
+#endif /* _SECURITY__PAM_TYPES_H */
+
#endif /* defined(solaris) || (defined(__SVR4) && defined(sun)) */
#endif /* _PAM_COMPAT_H */
diff --git a/contrib/libpam/libpam/include/security/_pam_macros.h b/contrib/libpam/libpam/include/security/_pam_macros.h
index b033aa63fab6..2827fabf77d0 100644
--- a/contrib/libpam/libpam/include/security/_pam_macros.h
+++ b/contrib/libpam/libpam/include/security/_pam_macros.h
@@ -9,7 +9,9 @@
/* a 'safe' version of strdup */
-extern char *strdup(const char *s);
+#include <string.h>
+#include <stdlib.h>
+
#define x_strdup(s) ( (s) ? strdup(s):NULL )
/* Good policy to strike out passwords with some characters not just
@@ -61,8 +63,10 @@ do { \
#include <stdio.h>
#include <sys/types.h>
#include <stdarg.h>
-#include <stdlib.h>
#include <errno.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
/*
* This is for debugging purposes ONLY. DO NOT use on live systems !!!
@@ -80,37 +84,55 @@ static void _pam_output_debug_info(const char *file, const char *fn
, const int line)
{
FILE *logfile;
- int must_close = 1;
-
- if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
+ int must_close = 1, fd;
+
+#ifdef O_NOFOLLOW
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
+#else
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
+#endif
+ if (!(logfile = fdopen(fd,"a"))) {
+ logfile = stderr;
+ must_close = 0;
+ close(fd);
+ }
+ } else {
logfile = stderr;
- must_close = 0;
+ must_close = 0;
}
fprintf(logfile,"[%s:%s(%d)] ",file, fn, line);
- if (must_close) {
- fflush(logfile);
+ fflush(logfile);
+ if (must_close)
fclose(logfile);
- }
}
static void _pam_output_debug(const char *format, ...)
{
va_list args;
FILE *logfile;
- int must_close = 1;
+ int must_close = 1, fd;
va_start(args, format);
- if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
- logfile = stderr;
- must_close = 0;
+#ifdef O_NOFOLLOW
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
+#else
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
+#endif
+ if (!(logfile = fdopen(fd,"a"))) {
+ logfile = stderr;
+ must_close = 0;
+ close(fd);
+ }
+ } else {
+ logfile = stderr;
+ must_close = 0;
}
vfprintf(logfile, format, args);
fprintf(logfile, "\n");
- if (must_close) {
- fflush(logfile);
+ fflush(logfile);
+ if (must_close)
fclose(logfile);
- }
va_end(args);
}
diff --git a/contrib/libpam/libpam/include/security/_pam_types.h b/contrib/libpam/libpam/include/security/_pam_types.h
index b68368b0c8e2..f0f30930fc69 100644
--- a/contrib/libpam/libpam/include/security/_pam_types.h
+++ b/contrib/libpam/libpam/include/security/_pam_types.h
@@ -1,7 +1,7 @@
/*
* <security/_pam_types.h>
*
- * $Id: _pam_types.h,v 1.10 1997/04/05 06:52:50 morgan Exp morgan $
+ * $Id: _pam_types.h,v 1.4 2001/01/22 06:07:29 agmorgan Exp $
*
* This file defines all of the types common to the Linux-PAM library
* applications and modules.
@@ -9,13 +9,16 @@
* Note, the copyright+license information is at end of file.
*
* Created: 1996/3/5 by AGM
- *
- * $Log$
*/
#ifndef _SECURITY__PAM_TYPES_H
#define _SECURITY__PAM_TYPES_H
+#ifndef __LIBPAM_VERSION
+# define __LIBPAM_VERSION __libpam_version
+#endif
+extern unsigned int __libpam_version;
+
/*
* include local definition for POSIX - NULL
*/
@@ -88,7 +91,10 @@ typedef struct pam_handle pam_handle_t;
calling again, verify that conversation
is completed */
-/* Add new #define's here */
+/*
+ * Add new #define's here - take care to also extend the libpam code:
+ * pam_strerror() and "libpam/pam_tokens.h" .
+ */
#define _PAM_RETURN_VALUES 32 /* this is the number of return values */
@@ -141,7 +147,6 @@ typedef struct pam_handle pam_handle_t;
#define PAM_USER_PROMPT 9 /* the prompt for getting a username */
#define PAM_FAIL_DELAY 10 /* app supplied function to override failure
delays */
-#define PAM_LOG_STATE 11 /* ident, facility etc. logging info */
/* ---------- Common Linux-PAM application/module PI ----------- */
@@ -178,50 +183,18 @@ extern char **pam_getenvlist(pam_handle_t *pamh);
* This item was added to accommodate event driven programs that need to
* manage delays more carefully. The function prototype for this data
* item is
- * void (*fail_delay)(int status, unsigned int delay);
+ * void (*fail_delay)(int status, unsigned int delay, void *appdata_ptr);
*/
#define HAVE_PAM_FAIL_DELAY
extern int pam_fail_delay(pam_handle_t *pamh, unsigned int musec_delay);
-/*
- * the standard libc interface for syslog suffers from some problems.
- * The first is that it is not thread safe. It is also three functions
- * where PAM only really needs a "log this" function. It also does
- * not provide modules and applications with information about whether
- * the log is currently open or not etc... All of these things mean
- * that we need to centralize PAM's logging facility. These two functions
- * provide this centralization. They are, however, just a gateway to
- * libc's openlog/syslog/closelog functions. Please note, your apps/modules
- * will likely start to segfault if you do not use this function for
- * system logging.
- */
-
-struct pam_log_state {
- char *ident;
- int option;
- int facility;
-};
-
-#ifndef LOG_ERR
-# include <syslog.h> /* this is a sad HACK. But we need LOG_CRIT etc.. */
-#endif
-
-#define PAM_LOG_STATE_IDENT "PAM"
-#define PAM_LOG_STATE_OPTION LOG_PID
-#define PAM_LOG_STATE_FACILITY LOG_AUTHPRIV
-
-#ifndef va_start
-# include <stdarg.h>
-#endif
-
-#define HAVE_PAM_SYSTEM_LOG
-extern void pam_vsystem_log(const pam_handle_t *pamh,
- const struct pam_log_state *log_state,
- int priority, const char *format, va_list args);
-extern void pam_system_log(const pam_handle_t *pamh,
- const struct pam_log_state *log_state,
- int priority, const char *format, ... );
+#include <syslog.h>
+#ifndef LOG_AUTHPRIV
+# ifdef LOG_PRIV
+# define LOG_AUTHPRIV LOG_PRIV
+# endif /* LOG_PRIV */
+#endif /* !LOG_AUTHPRIV */
#ifdef MEMORY_DEBUG
/*
@@ -246,14 +219,8 @@ extern void pam_system_log(const pam_handle_t *pamh,
#define PAM_RADIO_TYPE 5 /* yes/no/maybe conditionals */
/* This is for server client non-human interaction.. these are NOT
- part of the X/Open PAM specification (yet although Vipin has hinted
- that they may well be 1997/7/8) but are currently included for
- exploritory reasons. Basically, they are for the module to obtain a
- binary chunk of data from the client (via the server). Such data
- is intercepted by the server and unpacked in preparation for the
- module */
-
-#define PAM_BINARY_MSG 6
+ part of the X/Open PAM specification. */
+
#define PAM_BINARY_PROMPT 7
/* maximum size of messages/responses etc.. (these are mostly
@@ -280,10 +247,11 @@ struct pam_message {
struct {
u32 length; # network byte order
- unsigned char data[length];
+ unsigned char type;
+ unsigned char data[length-5];
};
- The 'libpam_client' library is designed around this flavor of
+ The 'libpamc' library is designed around this flavor of
message and should be used to handle this flavor of msg_style.
*/
diff --git a/contrib/libpam/libpam/include/security/pam_appl.h b/contrib/libpam/libpam/include/security/pam_appl.h
index d9c5eddd145b..69ee544ddcd9 100644
--- a/contrib/libpam/libpam/include/security/pam_appl.h
+++ b/contrib/libpam/libpam/include/security/pam_appl.h
@@ -10,27 +10,16 @@
* Created: 15-Jan-96 by TYT
* Last modified: 1996/3/5 by AGM
*
- * $Log: pam_appl.h,v $
- * Revision 1.5 1996/11/10 19:56:11 morgan
- * minor prototype change
- *
- * Revision 1.4 1996/03/16 22:38:17 morgan
- * made all of the pam_start input arguments constant
- *
- * Revision 1.3 1996/03/16 20:22:59 morgan
- * changed name comment at top of file.
- *
- * Revision 1.2 1996/03/09 20:39:06 morgan
- * added RCS information
- *
- *
- * $Id: pam_appl.h,v 1.5 1996/11/10 19:56:11 morgan Exp $
- *
+ * $Id: pam_appl.h,v 1.3 2000/11/19 23:54:02 agmorgan Exp $
*/
#ifndef _SECURITY_PAM_APPL_H
#define _SECURITY_PAM_APPL_H
+#ifdef __cplusplus
+extern "C" {
+#endif
+
#include <security/_pam_types.h> /* Linux-PAM common defined types */
/* -------------- The Linux-PAM Framework layer API ------------- */
@@ -58,6 +47,10 @@ extern int pam_close_session(pam_handle_t *pamh, int flags);
extern int pam_chauthtok(pam_handle_t *pamh, int flags);
+#ifdef __cplusplus
+}
+#endif
+
/* take care of any compatibility issues */
#include <security/_pam_compat.h>
diff --git a/contrib/libpam/libpam/include/security/pam_malloc.h b/contrib/libpam/libpam/include/security/pam_malloc.h
index b5865cd305ad..214bf77dff6c 100644
--- a/contrib/libpam/libpam/include/security/pam_malloc.h
+++ b/contrib/libpam/libpam/include/security/pam_malloc.h
@@ -1,9 +1,5 @@
-/* $Id: pam_malloc.h,v 1.1 1996/11/10 21:23:14 morgan Exp $
- *
- * $Log: pam_malloc.h,v $
- * Revision 1.1 1996/11/10 21:23:14 morgan
- * Initial revision
- *
+/*
+ * $Id: pam_malloc.h,v 1.2 2000/12/04 19:02:34 baggins Exp $
*/
/*
diff --git a/contrib/libpam/libpam/include/security/pam_modules.h b/contrib/libpam/libpam/include/security/pam_modules.h
index 6ba9cc66588a..1f20993fea3b 100644
--- a/contrib/libpam/libpam/include/security/pam_modules.h
+++ b/contrib/libpam/libpam/include/security/pam_modules.h
@@ -1,27 +1,7 @@
/*
* <security/pam_modules.h>
*
- * $Id: pam_modules.h,v 1.8 1997/01/04 20:14:42 morgan Exp morgan $
- *
- * This header file documents the PAM SPI --- that is, interface
- * between the PAM library and a PAM service library which is called
- * by the PAM library.
- *
- * Note, the copyright information is at end of file.
- *
- * $Log: pam_modules.h,v $
- * Revision 1.8 1997/01/04 20:14:42 morgan
- * moved PAM_DATA_SILENT to _pam_types.h so applications can use it too
- *
- * Revision 1.7 1996/11/10 19:57:08 morgan
- * pam_get_user prototype.
- *
- * Revision 1.6 1996/09/05 06:18:45 morgan
- * added some data error_status masks, changed prototype for cleanup()
- *
- * Revision 1.5 1996/06/02 07:58:37 morgan
- * altered the way in which modules obtain static prototypes for
- * functions
+ * $Id: pam_modules.h,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
*
*/
@@ -132,7 +112,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
#define PAM_PRELIM_CHECK 0x4000
/* The password service should update passwords Note: PAM_PRELIM_CHECK
- * and PAM_UPDATE_AUTHTOK can not both be set simultaneously! */
+ * and PAM_UPDATE_AUTHTOK cannot both be set simultaneously! */
#define PAM_UPDATE_AUTHTOK 0x2000
diff --git a/contrib/libpam/libpam/pam_account.c b/contrib/libpam/libpam/pam_account.c
index ffc01acd2a1b..71e04f15ccaf 100644
--- a/contrib/libpam/libpam/pam_account.c
+++ b/contrib/libpam/libpam/pam_account.c
@@ -6,8 +6,18 @@
int pam_acct_mgmt(pam_handle_t *pamh, int flags)
{
+ int retval;
+
D(("called"));
- IF_NO_PAMH("pam_acct_mgmt",pamh,PAM_SYSTEM_ERR);
- return _pam_dispatch(pamh, flags, PAM_ACCOUNT);
+ IF_NO_PAMH("pam_acct_mgmt", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
+
+ retval = _pam_dispatch(pamh, flags, PAM_ACCOUNT);
+
+ return retval;
}
diff --git a/contrib/libpam/libpam/pam_auth.c b/contrib/libpam/libpam/pam_auth.c
index ac461f5ba863..2645d8ad32d1 100644
--- a/contrib/libpam/libpam/pam_auth.c
+++ b/contrib/libpam/libpam/pam_auth.c
@@ -1,11 +1,7 @@
/*
* pam_auth.c -- PAM authentication
*
- * $Id: pam_auth.c,v 1.7 1997/04/05 06:53:52 morgan Exp morgan $
- *
- * $Log: pam_auth.c,v $
- * Revision 1.7 1997/04/05 06:53:52 morgan
- * fail-delay changes
+ * $Id: pam_auth.c,v 1.3 2001/01/22 06:07:28 agmorgan Exp $
*
*/
@@ -20,6 +16,13 @@ int pam_authenticate(pam_handle_t *pamh, int flags)
D(("pam_authenticate called"));
+ IF_NO_PAMH("pam_authenticate", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
+
if (pamh->former.choice == PAM_NOT_STACKED) {
_pam_sanitize(pamh);
_pam_start_timer(pamh); /* we try to make the time for a failure
@@ -27,7 +30,6 @@ int pam_authenticate(pam_handle_t *pamh, int flags)
fail */
}
- IF_NO_PAMH("pam_authenticate",pamh,PAM_SYSTEM_ERR);
retval = _pam_dispatch(pamh, flags, PAM_AUTHENTICATE);
if (retval != PAM_INCOMPLETE) {
@@ -45,9 +47,14 @@ int pam_setcred(pam_handle_t *pamh, int flags)
{
int retval;
+ D(("pam_setcred called"));
+
IF_NO_PAMH("pam_setcred", pamh, PAM_SYSTEM_ERR);
- D(("pam_setcred called"));
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
if (! flags) {
flags = PAM_ESTABLISH_CRED;
diff --git a/contrib/libpam/libpam/pam_data.c b/contrib/libpam/libpam/pam_data.c
index 397fb9d820d1..07bcd30d8b02 100644
--- a/contrib/libpam/libpam/pam_data.c
+++ b/contrib/libpam/libpam/pam_data.c
@@ -1,23 +1,7 @@
/* pam_data.c */
/*
- * $Id: pam_data.c,v 1.5 1996/12/01 03:14:13 morgan Exp $
- *
- * $Log: pam_data.c,v $
- * Revision 1.5 1996/12/01 03:14:13 morgan
- * use _pam_macros.h
- *
- * Revision 1.4 1996/11/10 19:59:56 morgan
- * internalized strdup for malloc debugging
- *
- * Revision 1.3 1996/09/05 06:10:31 morgan
- * changed type of cleanup(), added PAM_DATA_REPLACE to replacement
- * cleanup() call.
- *
- * Revision 1.2 1996/03/16 21:33:05 morgan
- * removed const from cleanup argument, also deleted comment about SUN stuff
- *
- *
+ * $Id: pam_data.c,v 1.2 2001/01/22 06:07:28 agmorgan Exp $
*/
#include <stdlib.h>
@@ -25,7 +9,26 @@
#include "pam_private.h"
-struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name);
+static struct pam_data *_pam_locate_data(const pam_handle_t *pamh,
+ const char *name)
+{
+ struct pam_data *data;
+
+ D(("called"));
+
+ IF_NO_PAMH("_pam_locate_data", pamh, NULL);
+
+ data = pamh->data;
+
+ while (data) {
+ if (!strcmp(data->name, name)) {
+ return data;
+ }
+ data = data->next;
+ }
+
+ return NULL;
+}
int pam_set_data(
pam_handle_t *pamh,
@@ -35,21 +38,27 @@ int pam_set_data(
{
struct pam_data *data_entry;
- IF_NO_PAMH("pam_set_data",pamh,PAM_SYSTEM_ERR);
+ D(("called"));
+
+ IF_NO_PAMH("pam_set_data", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_APP(pamh)) {
+ D(("called from application!?"));
+ return PAM_SYSTEM_ERR;
+ }
/* first check if there is some data already. If so clean it up */
if ((data_entry = _pam_locate_data(pamh, module_data_name))) {
if (data_entry->cleanup) {
- data_entry->cleanup(pamh, data_entry->data
- , PAM_DATA_REPLACE | PAM_SUCCESS );
+ data_entry->cleanup(pamh, data_entry->data,
+ PAM_DATA_REPLACE | PAM_SUCCESS );
}
} else if ((data_entry = malloc(sizeof(*data_entry)))) {
char *tname;
if ((tname = _pam_strdup(module_data_name)) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "pam_set_data: no memory for data name");
+ _pam_system_log(LOG_CRIT, "pam_set_data: no memory for data name");
_pam_drop(data_entry);
return PAM_BUF_ERR;
}
@@ -57,8 +66,7 @@ int pam_set_data(
pamh->data = data_entry;
data_entry->name = tname;
} else {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "pam_set_data: cannot allocate data entry");
+ _pam_system_log(LOG_CRIT, "pam_set_data: cannot allocate data entry");
return PAM_BUF_ERR;
}
@@ -75,7 +83,14 @@ int pam_get_data(
{
struct pam_data *data;
- IF_NO_PAMH("pam_get_data",pamh,PAM_SYSTEM_ERR);
+ D(("called"));
+
+ IF_NO_PAMH("pam_get_data", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_APP(pamh)) {
+ D(("called from application!?"));
+ return PAM_SYSTEM_ERR;
+ }
data = _pam_locate_data(pamh, module_data_name);
if (data) {
@@ -86,29 +101,14 @@ int pam_get_data(
return PAM_NO_MODULE_DATA;
}
-struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name)
-{
- struct pam_data *data;
-
- IF_NO_PAMH("_pam_locate_data",pamh,NULL);
- data = pamh->data;
-
- while (data) {
- if (!strcmp(data->name, name)) {
- return data;
- }
- data = data->next;
- }
-
- return NULL;
-}
-
void _pam_free_data(pam_handle_t *pamh, int status)
{
struct pam_data *last;
struct pam_data *data;
- IF_NO_PAMH("_pam_free_data",pamh,/* no return value for void fn */);
+ D(("called"));
+
+ IF_NO_PAMH("_pam_free_data", pamh, /* no return value for void fn */);
data = pamh->data;
while (data) {
diff --git a/contrib/libpam/libpam/pam_delay.c b/contrib/libpam/libpam/pam_delay.c
index e6950e2a966b..b414ecc4972d 100644
--- a/contrib/libpam/libpam/pam_delay.c
+++ b/contrib/libpam/libpam/pam_delay.c
@@ -1,12 +1,11 @@
/*
* pam_delay.c
*
- * Copyright (c) Andrew G. Morgan <morgan@linux.kernel.org> 1996-8
+ * Copyright (c) Andrew G. Morgan <morgan@kernel.org> 1996-9
* All rights reserved.
*
- * $Id: pam_delay.c,v 1.5 1997/04/05 06:54:19 morgan Exp $
+ * $Id: pam_delay.c,v 1.3 2001/01/22 06:07:28 agmorgan Exp $
*
- * $Log: pam_delay.c,v $
*/
/*
@@ -94,13 +93,20 @@ void _pam_await_timer(pam_handle_t *pamh, int status)
if (pamh->fail_delay.delay_fn_ptr) {
union {
const void *value;
- void (*fn)(int, unsigned);
+ void (*fn)(int, unsigned, void *);
} hack_fn_u;
+ void *appdata_ptr;
+
+ if (pamh->pam_conversation) {
+ appdata_ptr = pamh->pam_conversation->appdata_ptr;
+ } else {
+ appdata_ptr = NULL;
+ }
/* always call the applications delay function, even if
the delay is zero - indicate status */
hack_fn_u.value = pamh->fail_delay.delay_fn_ptr;
- hack_fn_u.fn(status, delay);
+ hack_fn_u.fn(status, delay, appdata_ptr);
} else if (status != PAM_SUCCESS && pamh->fail_delay.set) {
diff --git a/contrib/libpam/libpam/pam_dispatch.c b/contrib/libpam/libpam/pam_dispatch.c
index d0bbc3872103..ffb50f5226e8 100644
--- a/contrib/libpam/libpam/pam_dispatch.c
+++ b/contrib/libpam/libpam/pam_dispatch.c
@@ -1,9 +1,9 @@
/* pam_dispatch.c - handles module function dispatch */
/*
- * $Id: pam_dispatch.c,v 1.8 1997/01/04 20:04:09 morgan Exp morgan $
+ * Copyright (c) 1998 Andrew G. Morgan <morgan@kernel.org>
*
- * last modified by AGM
+ * $Id: pam_dispatch.c,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
*/
#include <stdlib.h>
@@ -28,7 +28,7 @@
*/
static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
- _pam_boolean resumed)
+ _pam_boolean resumed, int use_cached_chain)
{
int depth, impression, status, skip_depth;
@@ -38,9 +38,8 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
const char *service=NULL;
(void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service);
- pam_system_log(pamh, NULL, LOG_ERR,
- "no modules loaded for `%s' service",
- service ? service:"<unknown>" );
+ _pam_system_log(LOG_ERR, "no modules loaded for `%s' service",
+ service ? service:"<unknown>" );
service = NULL;
return PAM_MUST_FAIL_CODE;
}
@@ -63,7 +62,7 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
/* Loop through module logic stack */
for (depth=0 ; h != NULL ; h = h->next, ++depth) {
- int retval, action;
+ int retval, cached_retval, action;
/* skip leading modules if they have already returned */
if (depth < skip_depth) {
@@ -79,7 +78,7 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
retval = h->func(pamh, flags, h->argc, h->argv);
D(("module returned: %s", pam_strerror(pamh, retval)));
if (h->must_fail) {
- D(("module poorly listed in pam.conf; forcing failure"));
+ D(("module poorly listed in PAM config; forcing failure"));
retval = PAM_MUST_FAIL_CODE;
}
}
@@ -100,23 +99,57 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
return retval;
}
+ if (use_cached_chain) {
+ /* a former stack execution has frozen the chain */
+ cached_retval = *(h->cached_retval_p);
+ } else {
+ /* this stack execution is defining the frozen chain */
+ cached_retval = h->cached_retval = retval;
+ }
+
/* verify that the return value is a valid one */
- if (retval < PAM_SUCCESS || retval >= _PAM_RETURN_VALUES) {
+ if ((cached_retval < PAM_SUCCESS)
+ || (cached_retval >= _PAM_RETURN_VALUES)) {
retval = PAM_MUST_FAIL_CODE;
action = _PAM_ACTION_BAD;
} else {
- action = h->actions[retval];
+ /* We treat the current retval with some respect. It may
+ (for example, in the case of setcred) have a value that
+ needs to be propagated to the user. We want to use the
+ cached_retval to determine the modules to be executed
+ in the stacked chain, but we want to treat each
+ non-ignored module in the cached chain as now being
+ 'required'. We only need to treat the,
+ _PAM_ACTION_IGNORE, _PAM_ACTION_IS_JUMP and
+ _PAM_ACTION_RESET actions specially. */
+
+ action = h->actions[cached_retval];
}
+ D((stderr,
+ "use_cached_chain=%d action=%d cached_retval=%d retval=%d\n",
+ use_cached_chain, action, cached_retval, retval));
+
/* decide what to do */
switch (action) {
case _PAM_ACTION_RESET:
+
+ /* if (use_cached_chain) {
+ XXX - we need to consider the use_cached_chain case
+ do we want to trash accumulated info here..?
+ } */
+
impression = _PAM_UNDEF;
status = PAM_MUST_FAIL_CODE;
break;
case _PAM_ACTION_OK:
case _PAM_ACTION_DONE:
+
+ /* XXX - should we maintain cached_status and status in
+ the case of use_cached_chain? The same with BAD&DIE
+ below */
+
if ( impression == _PAM_UNDEF
|| (impression == _PAM_POSITIVE && status == PAM_SUCCESS) ) {
impression = _PAM_POSITIVE;
@@ -130,7 +163,7 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
case _PAM_ACTION_BAD:
case _PAM_ACTION_DIE:
#ifdef PAM_FAIL_NOW_ON
- if ( retval == PAM_ABORT ) {
+ if ( cached_retval == PAM_ABORT ) {
impression = _PAM_NEGATIVE;
status = PAM_PERM_DENIED;
goto decision_made;
@@ -146,6 +179,11 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
break;
case _PAM_ACTION_IGNORE:
+ /* if (use_cached_chain) {
+ XXX - when evaluating a cached
+ chain, do we still want to ignore the module's
+ return value?
+ } */
break;
/* if we get here, we expect action is a positive number --
@@ -153,6 +191,20 @@ static int _pam_dispatch_aux(pam_handle_t *pamh, int flags, struct handler *h,
default:
if ( _PAM_ACTION_IS_JUMP(action) ) {
+
+ /* If we are evaluating a cached chain, we treat this
+ module as required (aka _PAM_ACTION_OK) as well as
+ executing the jump. */
+
+ if (use_cached_chain) {
+ if (impression == _PAM_UNDEF
+ || (impression == _PAM_POSITIVE
+ && status == PAM_SUCCESS) ) {
+ impression = _PAM_POSITIVE;
+ status = retval;
+ }
+ }
+
/* this means that we need to skip #action stacked modules */
do {
h = h->next;
@@ -193,24 +245,32 @@ decision_made: /* by getting here we have made a decision */
int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
{
struct handler *h = NULL;
- int retval;
+ int retval, use_cached_chain;
_pam_boolean resumed;
- IF_NO_PAMH("_pam_dispatch",pamh,PAM_SYSTEM_ERR);
+ IF_NO_PAMH("_pam_dispatch", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from a module!?"));
+ return PAM_SYSTEM_ERR;
+ }
/* Load all modules, resolve all symbols */
if ((retval = _pam_init_handlers(pamh)) != PAM_SUCCESS) {
- pam_system_log(pamh, NULL, LOG_ERR, "unable to dispatch function");
+ _pam_system_log(LOG_ERR, "unable to dispatch function");
return retval;
}
+ use_cached_chain = 0; /* default to setting h->cached_retval */
+
switch (choice) {
case PAM_AUTHENTICATE:
h = pamh->handlers.conf.authenticate;
break;
case PAM_SETCRED:
h = pamh->handlers.conf.setcred;
+ use_cached_chain = 1;
break;
case PAM_ACCOUNT:
h = pamh->handlers.conf.acct_mgmt;
@@ -220,12 +280,16 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
break;
case PAM_CLOSE_SESSION:
h = pamh->handlers.conf.close_session;
+ use_cached_chain = 1;
break;
case PAM_CHAUTHTOK:
h = pamh->handlers.conf.chauthtok;
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ use_cached_chain = 1;
+ }
break;
default:
- pam_system_log(pamh, NULL, LOG_ERR, "undefined fn choice; %d", choice);
+ _pam_system_log(LOG_ERR, "undefined fn choice; %d", choice);
return PAM_ABORT;
}
@@ -256,9 +320,9 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
/* Did a module return an "incomplete state" last time? */
if (pamh->former.choice != PAM_NOT_STACKED) {
if (pamh->former.choice != choice) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "application failed to re-exec stack [%d:%d]",
- pamh->former.choice, choice);
+ _pam_system_log(LOG_ERR,
+ "application failed to re-exec stack [%d:%d]",
+ pamh->former.choice, choice);
return PAM_ABORT;
}
resumed = PAM_TRUE;
@@ -266,10 +330,14 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
resumed = PAM_FALSE;
}
+ __PAM_TO_MODULE(pamh);
+
/* call the list of module functions */
- retval = _pam_dispatch_aux(pamh, flags, h, resumed);
+ retval = _pam_dispatch_aux(pamh, flags, h, resumed, use_cached_chain);
resumed = PAM_FALSE;
+ __PAM_TO_APP(pamh);
+
/* Should we recall where to resume next time? */
if (retval == PAM_INCOMPLETE) {
D(("module [%d] returned PAM_INCOMPLETE"));
@@ -281,6 +349,3 @@ int _pam_dispatch(pam_handle_t *pamh, int flags, int choice)
return retval;
}
-/*
- * $Log: pam_dispatch.c,v $
- */
diff --git a/contrib/libpam/libpam/pam_end.c b/contrib/libpam/libpam/pam_end.c
index 34f98f579779..53e346cc4e98 100644
--- a/contrib/libpam/libpam/pam_end.c
+++ b/contrib/libpam/libpam/pam_end.c
@@ -1,9 +1,7 @@
/* pam_end.c */
/*
- * $Id: pam_end.c,v 1.5 1996/12/01 03:14:13 morgan Exp $
- *
- * $Log: pam_end.c,v $
+ * $Id: pam_end.c,v 1.2 2001/01/22 06:07:28 agmorgan Exp $
*/
#include <stdlib.h>
@@ -14,9 +12,14 @@ int pam_end(pam_handle_t *pamh, int pam_status)
{
int ret;
+ D(("entering pam_end()"));
+
IF_NO_PAMH("pam_end", pamh, PAM_SYSTEM_ERR);
- D(("entering pam_end()"));
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
/* first liberate the modules (it is not inconcevible that the
modules may need to use the service_name etc. to clean up) */
@@ -64,9 +67,6 @@ int pam_end(pam_handle_t *pamh, int pam_status)
_pam_drop(pamh->pam_conversation);
pamh->fail_delay.delay_fn_ptr = NULL;
- _pam_overwrite(pamh->pam_default_log.ident);
- _pam_drop(pamh->pam_default_log.ident);
-
/* and finally liberate the memory for the pam_handle structure */
_pam_drop(pamh);
diff --git a/contrib/libpam/libpam/pam_env.c b/contrib/libpam/libpam/pam_env.c
index 2632b81342a2..a2b212a98545 100644
--- a/contrib/libpam/libpam/pam_env.c
+++ b/contrib/libpam/libpam/pam_env.c
@@ -7,14 +7,7 @@
* This file was written from a "hint" provided by the people at SUN.
* and the X/Open XSSO draft of March 1997.
*
- * $Id: pam_env.c,v 1.2 1997/02/15 15:56:48 morgan Exp morgan $
- *
- * $Log: pam_env.c,v $
- * Revision 1.2 1997/02/15 15:56:48 morgan
- * liberate pamh->env structure too!
- *
- * Revision 1.1 1996/12/01 03:14:13 morgan
- * Initial revision
+ * $Id: pam_env.c,v 1.2 2001/01/22 06:07:28 agmorgan Exp $
*/
#include <string.h>
@@ -54,6 +47,7 @@ static void _pam_dump_env(pam_handle_t *pamh)
int _pam_make_env(pam_handle_t *pamh)
{
D(("called."));
+
IF_NO_PAMH("_pam_make_env", pamh, PAM_ABORT);
/*
@@ -62,7 +56,7 @@ int _pam_make_env(pam_handle_t *pamh)
pamh->env = (struct pam_environ *) malloc(sizeof(struct pam_environ));
if (pamh->env == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT, "_pam_make_env: out of memory");
+ _pam_system_log(LOG_CRIT, "_pam_make_env: out of memory");
return PAM_BUF_ERR;
}
@@ -72,8 +66,7 @@ int _pam_make_env(pam_handle_t *pamh)
pamh->env->list = (char **)calloc( PAM_ENV_CHUNK, sizeof(char *) );
if (pamh->env->list == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "_pam_make_env: no memory for list");
+ _pam_system_log(LOG_CRIT, "_pam_make_env: no memory for list");
_pam_drop(pamh->env);
return PAM_BUF_ERR;
}
@@ -163,8 +156,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
IF_NO_PAMH("pam_putenv", pamh, PAM_ABORT);
if (name_value == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_putenv: no variable indicated");
+ _pam_system_log(LOG_ERR, "pam_putenv: no variable indicated");
return PAM_PERM_DENIED;
}
@@ -174,7 +166,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
for (l2eq=0; name_value[l2eq] && name_value[l2eq] != '='; ++l2eq);
if (l2eq <= 0) {
- pam_system_log(pamh, NULL, LOG_ERR, "pam_putenv: bad variable");
+ _pam_system_log(LOG_ERR, "pam_putenv: bad variable");
return PAM_BAD_ITEM;
}
@@ -183,8 +175,8 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
*/
if (pamh->env == NULL || pamh->env->list == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR, "pam_putenv: no env%s found"
- , pamh->env == NULL ? "":"-list");
+ _pam_system_log(LOG_ERR, "pam_putenv: no env%s found",
+ pamh->env == NULL ? "":"-list");
return PAM_ABORT;
}
@@ -206,8 +198,8 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
, sizeof(char *) );
if (tmp == NULL) {
/* nothing has changed - old env intact */
- pam_system_log(pamh, NULL, LOG_CRIT,
- "pam_putenv: cannot grow environment");
+ _pam_system_log(LOG_CRIT,
+ "pam_putenv: cannot grow environment");
return PAM_BUF_ERR;
}
@@ -258,8 +250,7 @@ int pam_putenv(pam_handle_t *pamh, const char *name_value)
/* getting to here implies we are deleting an item */
if (item < 0) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_putenv: delete non-existent entry; %s",
+ _pam_system_log(LOG_ERR, "pam_putenv: delete non-existent entry; %s",
name_value);
return PAM_BAD_ITEM;
}
@@ -298,14 +289,13 @@ const char *pam_getenv(pam_handle_t *pamh, const char *name)
IF_NO_PAMH("pam_getenv", pamh, NULL);
if (name == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_getenv: no variable indicated");
+ _pam_system_log(LOG_ERR, "pam_getenv: no variable indicated");
return NULL;
}
if (pamh->env == NULL || pamh->env->list == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR, "pam_getenv: no env%s found",
- pamh->env == NULL ? "":"-list" );
+ _pam_system_log(LOG_ERR, "pam_getenv: no env%s found",
+ pamh->env == NULL ? "":"-list" );
return NULL;
}
@@ -371,25 +361,22 @@ char **pam_getenvlist(pam_handle_t *pamh)
IF_NO_PAMH("pam_getenvlist", pamh, NULL);
if (pamh->env == NULL || pamh->env->list == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_getenvlist: no env%s found",
- pamh->env == NULL ? "":"-list" );
+ _pam_system_log(LOG_ERR, "pam_getenvlist: no env%s found",
+ pamh->env == NULL ? "":"-list" );
return NULL;
}
/* some quick checks */
if (pamh->env->requested > pamh->env->entries) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_getenvlist: environment corruption");
+ _pam_system_log(LOG_ERR, "pam_getenvlist: environment corruption");
_pam_dump_env(pamh); /* only active when debugging */
return NULL;
}
for (i=pamh->env->requested-1; i-- > 0; ) {
if (pamh->env->list[i] == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_getenvlist: environment broken");
+ _pam_system_log(LOG_ERR, "pam_getenvlist: environment broken");
_pam_dump_env(pamh); /* only active when debugging */
return NULL; /* somehow we've broken the environment!? */
}
diff --git a/contrib/libpam/libpam/pam_handlers.c b/contrib/libpam/libpam/pam_handlers.c
index 53d77158edf5..7ae7174ecb32 100644
--- a/contrib/libpam/libpam/pam_handlers.c
+++ b/contrib/libpam/libpam/pam_handlers.c
@@ -4,7 +4,7 @@
* created by Marc Ewing.
* Currently maintained by Andrew G. Morgan <morgan@linux.kernel.org>
*
- * $Id: pam_handlers.c,v 1.17 1997/04/05 06:55:24 morgan Exp morgan $
+ * $Id: pam_handlers.c,v 1.3 2001/02/05 06:50:41 agmorgan Exp $
*
*/
@@ -13,11 +13,13 @@
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
-#ifdef PAM_SHL
-# include <dl.h>
-#else
-# include <dlfcn.h>
-#endif
+#ifdef PAM_DYNAMIC
+# ifdef PAM_SHL
+# include <dl.h>
+# else /* PAM_SHL */
+# include <dlfcn.h>
+# endif /* PAM_SHL */
+#endif /* PAM_DYNAMIC */
#include <fcntl.h>
#include <unistd.h>
@@ -33,8 +35,9 @@
# define SHLIB_SYM_PREFIX ""
#endif
-#define BUF_SIZE 1024
-#define MODULE_CHUNK 4
+#define BUF_SIZE 1024
+#define MODULE_CHUNK 4
+#define UNKNOWN_MODULE_PATH "<*unknown module path*>"
static int _pam_assemble_line(FILE *f, char *buf, int buf_len);
@@ -110,9 +113,8 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f
} else {
/* Illegal module type */
D(("_pam_init_handlers: bad module type: %s", tok));
- pam_system_log(pamh, NULL, LOG_ERR,
- "(%s) illegal module type: %s"
- , this_service, tok);
+ _pam_system_log(LOG_ERR, "(%s) illegal module type: %s",
+ this_service, tok);
module_type = PAM_T_AUTH; /* most sensitive */
must_fail = 1; /* install as normal but fail when dispatched */
}
@@ -162,8 +164,8 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f
} else {
/* no module name given */
D(("_pam_init_handlers: no module name supplied"));
- pam_system_log(pamh, NULL, LOG_ERR,
- "(%s) no module name supplied", this_service);
+ _pam_system_log(LOG_ERR,
+ "(%s) no module name supplied", this_service);
mod_path = NULL;
must_fail = 1;
}
@@ -198,8 +200,6 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f
actions[y]>0 ? "jump":
_pam_token_actions[-actions[y]]));
}
- fprintf(stderr, "pause to look at debugging: ");
- getchar();
}
#endif
@@ -207,8 +207,7 @@ static int _pam_parse_conf_file(pam_handle_t *pamh, FILE *f
, module_type, actions, mod_path
, argc, argv, argvlen);
if (res != PAM_SUCCESS) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "error loading %s", mod_path);
+ _pam_system_log(LOG_ERR, "error loading %s", mod_path);
D(("failed to load module - aborting"));
return PAM_ABORT;
}
@@ -240,8 +239,8 @@ int _pam_init_handlers(pam_handle_t *pamh)
if (! pamh->handlers.module) {
if ((pamh->handlers.module =
malloc(MODULE_CHUNK * sizeof(struct loaded_module))) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "_pam_init_handlers: no memory loading module");
+ _pam_system_log(LOG_CRIT,
+ "_pam_init_handlers: no memory loading module");
return PAM_BUF_ERR;
}
pamh->handlers.modules_allocated = MODULE_CHUNK;
@@ -258,9 +257,8 @@ int _pam_init_handlers(pam_handle_t *pamh)
int fd_tmp;
if ((fd_tmp = open( PAM_LOCK_FILE, O_RDONLY )) != -1) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: PAM lockfile ("
- PAM_LOCK_FILE ") exists - aborting");
+ _pam_system_log(LOG_ERR, "_pam_init_handlers: PAM lockfile ("
+ PAM_LOCK_FILE ") exists - aborting");
(void) close(fd_tmp);
/*
* to avoid swamping the system with requests
@@ -289,9 +287,9 @@ int _pam_init_handlers(pam_handle_t *pamh)
filename = malloc(sizeof(PAM_CONFIG_DF)
+strlen(pamh->service_name));
if (filename == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: no memory; service %s",
- pamh->service_name);
+ _pam_system_log(LOG_ERR,
+ "_pam_init_handlers: no memory; service %s",
+ pamh->service_name);
return PAM_BUF_ERR;
}
sprintf(filename, PAM_CONFIG_DF, pamh->service_name);
@@ -306,12 +304,11 @@ int _pam_init_handlers(pam_handle_t *pamh)
);
fclose(f);
if (retval != PAM_SUCCESS) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: error reading %s",
- filename);
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: [%s]",
- pam_strerror(pamh, retval));
+ _pam_system_log(LOG_ERR,
+ "_pam_init_handlers: error reading %s",
+ filename);
+ _pam_system_log(LOG_ERR, "_pam_init_handlers: [%s]",
+ pam_strerror(pamh, retval));
} else {
read_something = 1;
}
@@ -348,20 +345,20 @@ int _pam_init_handlers(pam_handle_t *pamh)
);
fclose(f);
if (retval != PAM_SUCCESS) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: error reading %s",
- PAM_DEFAULT_SERVICE_FILE);
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: [%s]",
- pam_strerror(pamh, retval));
+ _pam_system_log(LOG_ERR,
+ "_pam_init_handlers: error reading %s",
+ PAM_DEFAULT_SERVICE_FILE);
+ _pam_system_log(LOG_ERR,
+ "_pam_init_handlers: [%s]",
+ pam_strerror(pamh, retval));
} else {
read_something = 1;
}
} else {
D(("unable to open %s", PAM_DEFAULT_SERVICE_FILE));
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: no default config %s",
- PAM_DEFAULT_SERVICE_FILE);
+ _pam_system_log(LOG_ERR,
+ "_pam_init_handlers: no default config %s",
+ PAM_DEFAULT_SERVICE_FILE);
}
if (!read_something) { /* nothing read successfully */
retval = PAM_ABORT;
@@ -369,9 +366,8 @@ int _pam_init_handlers(pam_handle_t *pamh)
}
} else {
if ((f = fopen(PAM_CONFIG, "r")) == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "_pam_init_handlers: could not open "
- PAM_CONFIG );
+ _pam_system_log(LOG_ERR, "_pam_init_handlers: could not open "
+ PAM_CONFIG );
return PAM_ABORT;
}
@@ -388,8 +384,7 @@ int _pam_init_handlers(pam_handle_t *pamh)
if (retval != PAM_SUCCESS) {
/* Read error */
- pam_system_log(pamh, NULL, LOG_ERR,
- "error reading PAM configuration file");
+ _pam_system_log(LOG_ERR, "error reading PAM configuration file");
return PAM_ABORT;
}
@@ -404,7 +399,7 @@ int _pam_init_handlers(pam_handle_t *pamh)
* preceeded by lines of comments and also extended with "\\\n"
*/
-int _pam_assemble_line(FILE *f, char *buffer, int buf_len)
+static int _pam_assemble_line(FILE *f, char *buffer, int buf_len)
{
char *p = buffer;
char *s, *os;
@@ -506,12 +501,20 @@ int _pam_add_handler(pam_handle_t *pamh
IF_NO_PAMH("_pam_add_handler",pamh,PAM_SYSTEM_ERR);
/* if NULL set to something that can be searched for */
- if (mod_path == NULL) {
- mod_path = "<*unknown module path*>";
- } else if (mod_path[0] != '/') {
+ switch (mod_path != NULL) {
+ default:
+ if (mod_path[0] == '/') {
+ break;
+ }
mod_full_path = malloc(sizeof(DEFAULT_MODULE_PATH)+strlen(mod_path));
- sprintf(mod_full_path, DEFAULT_MODULE_PATH "%s", mod_path);
- mod_path = mod_full_path;
+ if (mod_full_path) {
+ sprintf(mod_full_path, DEFAULT_MODULE_PATH "%s", mod_path);
+ mod_path = mod_full_path;
+ break;
+ }
+ _pam_system_log(LOG_CRIT, "cannot malloc full mod path");
+ case 0:
+ mod_path = UNKNOWN_MODULE_PATH;
}
D(("_pam_add_handler: adding type %d, module `%s'",type,mod_path));
@@ -533,8 +536,8 @@ int _pam_add_handler(pam_handle_t *pamh
*sizeof(struct loaded_module));
if (tmp == NULL) {
D(("cannot enlarge module pointer memory"));
- pam_system_log(pamh, NULL, LOG_ERR,
- "realloc returned NULL in _pam_add_handler");
+ _pam_system_log(LOG_ERR,
+ "realloc returned NULL in _pam_add_handler");
_pam_drop(mod_full_path);
return PAM_ABORT;
}
@@ -556,10 +559,9 @@ int _pam_add_handler(pam_handle_t *pamh
D(("_pam_add_handler: dlopen'ed"));
if (mod->dl_handle == NULL) {
D(("_pam_add_handler: dlopen(%s) failed", mod_path));
- pam_system_log(pamh, NULL, LOG_ERR, "unable to dlopen(%s)",
- mod_path);
+ _pam_system_log(LOG_ERR, "unable to dlopen(%s)", mod_path);
# ifndef PAM_SHL
- pam_system_log(pamh, NULL, LOG_ERR, "[dlerror: %s]", dlerror());
+ _pam_system_log(LOG_ERR, "[dlerror: %s]", dlerror());
# endif /* PAM_SHL */
/* Don't abort yet; static code may be able to find function.
* But defaults to abort if nothing found below... */
@@ -579,8 +581,8 @@ int _pam_add_handler(pam_handle_t *pamh
if (mod->dl_handle == NULL) {
D(("_pam_add_handler: unable to find static handler %s",
mod_path));
- pam_system_log(pamh, NULL, LOG_ERR,
- "unable to open static handler %s", mod_path);
+ _pam_system_log(LOG_ERR,
+ "unable to open static handler %s", mod_path);
/* Didn't find module in dynamic or static..will mark bad */
} else {
D(("static module added successfully"));
@@ -595,16 +597,14 @@ int _pam_add_handler(pam_handle_t *pamh
mod->dl_handle = NULL;
mod->type = PAM_MT_FAULTY_MOD;
pamh->handlers.modules_used++;
- pam_system_log(pamh, NULL, LOG_ERR,
- "adding faulty module: %s", mod_path);
+ _pam_system_log(LOG_ERR, "adding faulty module: %s", mod_path);
success = PAM_SUCCESS; /* We have successfully added a module */
}
/* indicate its name - later we will search for it by this */
if ((mod->name = _pam_strdup(mod_path)) == NULL) {
D(("_pam_handler: couldn't get memory for mod_path"));
- pam_system_log(pamh, NULL, LOG_ERR,
- "no memory for module path", mod_path);
+ _pam_system_log(LOG_ERR, "no memory for module path", mod_path);
success = PAM_ABORT;
}
@@ -693,9 +693,9 @@ int _pam_add_handler(pam_handle_t *pamh
mod->type != PAM_MT_FAULTY_MOD
) {
D(("_pam_add_handlers: illegal module library type; %d", mod->type));
- pam_system_log(pamh, NULL, LOG_ERR,
- "internal error: module library type not known: %s;%d",
- sym, mod->type);
+ _pam_system_log(LOG_ERR,
+ "internal error: module library type not known: %s;%d",
+ sym, mod->type);
return PAM_ABORT;
}
@@ -710,15 +710,13 @@ int _pam_add_handler(pam_handle_t *pamh
(func = (servicefn) dlsym(mod->dl_handle, sym)) == NULL
# endif /* PAM_SHL */
) {
- pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
- sym);
+ _pam_system_log(LOG_ERR, "unable to resolve symbol: %s", sym);
}
#endif
#ifdef PAM_STATIC
if ((mod->type == PAM_MT_STATIC_MOD) &&
(func = (servicefn)_pam_get_static_sym(mod->dl_handle, sym)) == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "unable to resolve static symbol: %s", sym);
+ _pam_system_log(LOG_ERR, "unable to resolve static symbol: %s", sym);
}
#endif
if (sym2) {
@@ -731,16 +729,14 @@ int _pam_add_handler(pam_handle_t *pamh
(func2 = (servicefn) dlsym(mod->dl_handle, sym2)) == NULL
# endif /* PAM_SHL */
) {
- pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
- sym2);
+ _pam_system_log(LOG_ERR, "unable to resolve symbol: %s", sym2);
}
#endif
#ifdef PAM_STATIC
if ((mod->type == PAM_MT_STATIC_MOD) &&
(func2 = (servicefn)_pam_get_static_sym(mod->dl_handle, sym2))
== NULL) {
- pam_system_log(pamh, NULL, LOG_ERR, "unable to resolve symbol: %s",
- sym2);
+ _pam_system_log(LOG_ERR, "unable to resolve symbol: %s", sym2);
}
#endif
}
@@ -753,14 +749,15 @@ int _pam_add_handler(pam_handle_t *pamh
}
if ((*handler_p = malloc(sizeof(struct handler))) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "cannot malloc struct handler #1");
+ _pam_system_log(LOG_CRIT, "cannot malloc struct handler #1");
return (PAM_ABORT);
}
(*handler_p)->must_fail = must_fail; /* failure forced? */
(*handler_p)->func = func;
memcpy((*handler_p)->actions,actions,sizeof((*handler_p)->actions));
+ (*handler_p)->cached_retval = -1; /* error */
+ (*handler_p)->cached_retval_p = &((*handler_p)->cached_retval);
(*handler_p)->argc = argc;
(*handler_p)->argv = argv; /* not a copy */
(*handler_p)->next = NULL;
@@ -773,19 +770,20 @@ int _pam_add_handler(pam_handle_t *pamh
}
if ((*handler_p2 = malloc(sizeof(struct handler))) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "cannot malloc struct handler #2");
+ _pam_system_log(LOG_CRIT, "cannot malloc struct handler #2");
return (PAM_ABORT);
}
(*handler_p2)->must_fail = must_fail; /* failure forced? */
(*handler_p2)->func = func2;
memcpy((*handler_p2)->actions,actions,sizeof((*handler_p2)->actions));
+ (*handler_p2)->cached_retval = -1; /* ignored */
+ /* Note, this next entry points to the handler_p value! */
+ (*handler_p2)->cached_retval_p = &((*handler_p)->cached_retval);
(*handler_p2)->argc = argc;
if (argv) {
if (((*handler_p2)->argv = malloc(argvlen)) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "cannot malloc argv for handler #2");
+ _pam_system_log(LOG_CRIT, "cannot malloc argv for handler #2");
return (PAM_ABORT);
}
memcpy((*handler_p2)->argv, argv, argvlen);
@@ -816,11 +814,13 @@ int _pam_free_handlers(pam_handle_t *pamh)
D(("_pam_free_handlers: dlclose(%s)", mod->name));
free(mod->name);
#ifdef PAM_DYNAMIC
+ if (mod->type == PAM_MT_DYNAMIC_MOD) {
# ifdef PAM_SHL
- if (mod->type == PAM_MT_DYNAMIC_MOD) shl_unload(mod->dl_handle);
+ shl_unload(mod->dl_handle);
# else
- if (mod->type == PAM_MT_DYNAMIC_MOD) dlclose(mod->dl_handle);
+ dlclose(mod->dl_handle);
# endif
+ }
#endif
mod++;
pamh->handlers.modules_used--;
diff --git a/contrib/libpam/libpam/pam_item.c b/contrib/libpam/libpam/pam_item.c
index 0e8142bf5ce4..eec341f7e11b 100644
--- a/contrib/libpam/libpam/pam_item.c
+++ b/contrib/libpam/libpam/pam_item.c
@@ -1,9 +1,7 @@
/* pam_item.c */
/*
- * $Id: pam_item.c,v 1.8 1997/02/15 15:58:49 morgan Exp morgan $
- *
- * $Log: pam_item.c,v $
+ * $Id: pam_item.c,v 1.3 2001/01/22 06:07:28 agmorgan Exp $
*/
#include <ctype.h>
@@ -23,12 +21,13 @@
} \
}
+/* handy version id */
+
+unsigned int __libpam_version = LIBPAM_VERSION;
+
/* functions */
-int pam_set_item (
- pam_handle_t *pamh,
- int item_type,
- const void *item)
+int pam_set_item (pam_handle_t *pamh, int item_type, const void *item)
{
int retval;
@@ -39,6 +38,7 @@ int pam_set_item (
retval = PAM_SUCCESS;
switch (item_type) {
+
case PAM_SERVICE:
/* Setting handlers_loaded to 0 will cause the handlers
* to be reloaded on the next call to a service module.
@@ -51,57 +51,72 @@ int pam_set_item (
*tmp = tolower(*tmp); /* require lower case */
}
break;
+
case PAM_USER:
RESET(pamh->user, item);
break;
+
case PAM_USER_PROMPT:
RESET(pamh->prompt, item);
break;
+
case PAM_TTY:
D(("setting tty to %s", item));
RESET(pamh->tty, item);
break;
+
case PAM_RUSER:
RESET(pamh->ruser, item);
break;
+
case PAM_RHOST:
RESET(pamh->rhost, item);
break;
+
case PAM_AUTHTOK:
- /*
- * The man page says this is only supposed to be available to
- * the module providers. In order to use this item the app
- * has to #include <security/pam_modules.h>. This is something
- * it is *not* supposed to do with "Linux-"PAM! - AGM.
- */
- {
- char *_TMP_ = pamh->authtok;
- if (_TMP_ == item) /* not changed so leave alone */
- break;
- pamh->authtok = (item) ? _pam_strdup(item) : NULL;
- if (_TMP_) {
- _pam_overwrite(_TMP_);
- free(_TMP_);
+ /*
+ * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
+ * modules.
+ */
+ if (__PAM_FROM_MODULE(pamh)) {
+ char *_TMP_ = pamh->authtok;
+ if (_TMP_ == item) /* not changed so leave alone */
+ break;
+ pamh->authtok = (item) ? _pam_strdup(item) : NULL;
+ if (_TMP_) {
+ _pam_overwrite(_TMP_);
+ free(_TMP_);
+ }
+ } else {
+ retval = PAM_BAD_ITEM;
}
+
break;
- }
+
case PAM_OLDAUTHTOK:
- /* See note above. */
- {
- char *_TMP_ = pamh->oldauthtok;
- if (_TMP_ == item) /* not changed so leave alone */
- break;
- pamh->oldauthtok = (item) ? _pam_strdup(item) : NULL;
- if (_TMP_) {
- _pam_overwrite(_TMP_);
- free(_TMP_);
+ /*
+ * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
+ * modules.
+ */
+ if (__PAM_FROM_MODULE(pamh)) {
+ char *_TMP_ = pamh->oldauthtok;
+ if (_TMP_ == item) /* not changed so leave alone */
+ break;
+ pamh->oldauthtok = (item) ? _pam_strdup(item) : NULL;
+ if (_TMP_) {
+ _pam_overwrite(_TMP_);
+ free(_TMP_);
+ }
+ } else {
+ retval = PAM_BAD_ITEM;
}
+
break;
- }
+
case PAM_CONV: /* want to change the conversation function */
if (item == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_set_item: attempt to set conv() to NULL");
+ _pam_system_log(LOG_ERR,
+ "pam_set_item: attempt to set conv() to NULL");
retval = PAM_PERM_DENIED;
} else {
struct pam_conv *tconv;
@@ -109,8 +124,8 @@ int pam_set_item (
if ((tconv=
(struct pam_conv *) malloc(sizeof(struct pam_conv))
) == NULL) {
- pam_system_log(pamh, NULL, LOG_CRIT,
- "pam_set_item: malloc failed for pam_conv");
+ _pam_system_log(LOG_CRIT,
+ "pam_set_item: malloc failed for pam_conv");
retval = PAM_BUF_ERR;
} else {
memcpy(tconv, item, sizeof(struct pam_conv));
@@ -119,48 +134,28 @@ int pam_set_item (
}
}
break;
+
case PAM_FAIL_DELAY:
pamh->fail_delay.delay_fn_ptr = item;
break;
- case PAM_LOG_STATE:
- {
- char *old_ident = pamh->pam_default_log.ident;
-
- if (item == NULL) {
- /* reset the default state */
- pamh->pam_default_log.ident = x_strdup(PAM_LOG_STATE_IDENT);
- pamh->pam_default_log.option = PAM_LOG_STATE_OPTION;
- pamh->pam_default_log.facility = PAM_LOG_STATE_FACILITY;
- } else {
- const struct pam_log_state *state = item;
- pamh->pam_default_log.ident = x_strdup(state->ident);
- pamh->pam_default_log.option = state->option;
- pamh->pam_default_log.facility = state->facility;
- }
- _pam_overwrite(old_ident);
- _pam_drop(old_ident);
-
- break;
- }
default:
retval = PAM_BAD_ITEM;
}
- return (retval);
+ return retval;
}
-int pam_get_item (
- const pam_handle_t *pamh,
- int item_type,
- const void **item)
+int pam_get_item (const pam_handle_t *pamh, int item_type, const void **item)
{
+ int retval = PAM_SUCCESS;
+
D(("called."));
- IF_NO_PAMH("pam_get_item",pamh,PAM_SYSTEM_ERR);
+ IF_NO_PAMH("pam_get_item", pamh, PAM_SYSTEM_ERR);
if (item == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_get_item: nowhere to place requested item");
+ _pam_system_log(LOG_ERR,
+ "pam_get_item: nowhere to place requested item");
return PAM_PERM_DENIED;
}
@@ -168,46 +163,72 @@ int pam_get_item (
case PAM_SERVICE:
*item = pamh->service_name;
break;
+
case PAM_USER:
+ D(("returning user=%s", pamh->user));
*item = pamh->user;
break;
+
case PAM_USER_PROMPT:
+ D(("returning userprompt=%s", pamh->user));
*item = pamh->prompt;
break;
+
case PAM_TTY:
D(("returning tty=%s", pamh->tty));
*item = pamh->tty;
break;
+
case PAM_RUSER:
*item = pamh->ruser;
break;
+
case PAM_RHOST:
*item = pamh->rhost;
break;
+
case PAM_AUTHTOK:
- *item = pamh->authtok;
+ /*
+ * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
+ * modules.
+ */
+ if (__PAM_FROM_MODULE(pamh)) {
+ *item = pamh->authtok;
+ } else {
+ retval = PAM_BAD_ITEM;
+ }
break;
+
case PAM_OLDAUTHTOK:
- *item = pamh->oldauthtok;
+ /*
+ * PAM_AUTHTOK and PAM_OLDAUTHTOK are only accessible from
+ * modules.
+ */
+ if (__PAM_FROM_MODULE(pamh)) {
+ *item = pamh->oldauthtok;
+ } else {
+ retval = PAM_BAD_ITEM;
+ }
break;
+
case PAM_CONV:
*item = pamh->pam_conversation;
break;
+
case PAM_FAIL_DELAY:
*item = pamh->fail_delay.delay_fn_ptr;
break;
- case PAM_LOG_STATE:
- *item = &(pamh->pam_default_log);
- break;
+
default:
- /* XXX - I made this up */
- return PAM_BAD_ITEM;
+ retval = PAM_BAD_ITEM;
}
- return PAM_SUCCESS;
+ return retval;
}
-/* added by AGM 1996/3/2 */
+/*
+ * This function is the 'preferred method to obtain the username'.
+ */
int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
{
@@ -220,14 +241,12 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
IF_NO_PAMH("pam_get_user", pamh, PAM_SYSTEM_ERR);
if (pamh->pam_conversation == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_get_user: no conv element in pamh");
+ _pam_system_log(LOG_ERR, "pam_get_user: no conv element in pamh");
return PAM_SERVICE_ERR;
}
if (user == NULL) { /* ensure the the module has suplied a destination */
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_get_user: nowhere to record username");
+ _pam_system_log(LOG_ERR, "pam_get_user: nowhere to record username");
return PAM_PERM_DENIED;
} else
*user = NULL;
@@ -251,7 +270,7 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
if (pamh->former.want_user) {
/* must have a prompt to resume with */
if (! pamh->former.prompt) {
- pam_system_log(pamh, NULL, LOG_ERR,
+ _pam_system_log(LOG_ERR,
"pam_get_user: failed to resume with prompt"
);
return PAM_ABORT;
@@ -259,8 +278,8 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
/* must be the same prompt as last time */
if (strcmp(pamh->former.prompt, use_prompt)) {
- pam_system_log(pamh, NULL, LOG_ERR,
- "pam_get_user: resumed with different prompt");
+ _pam_system_log(LOG_ERR,
+ "pam_get_user: resumed with different prompt");
return PAM_ABORT;
}
@@ -309,5 +328,6 @@ int pam_get_user(pam_handle_t *pamh, const char **user, const char *prompt)
_pam_drop_reply(resp, 1);
}
+ D(("completed"));
return retval; /* pass on any error from conversation */
}
diff --git a/contrib/libpam/libpam/pam_log.c b/contrib/libpam/libpam/pam_log.c
index 9eddf29ba0ee..c42fe01559df 100644
--- a/contrib/libpam/libpam/pam_log.c
+++ b/contrib/libpam/libpam/pam_log.c
@@ -1,17 +1,16 @@
/*
* pam_log.c -- PAM system logging
*
- * $Id$
+ * $Id: pam_log.c,v 1.2 2000/11/19 23:54:02 agmorgan Exp $
*
- * $Log$
*/
+#include "pam_private.h"
+
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
-#include "pam_private.h"
-
#ifdef __hpux
# include <stdio.h>
# include <syslog.h>
@@ -342,84 +341,35 @@ vsyslog(priority, fmt, va_alist)
}
#endif /* __hpux */
-void pam_vsystem_log(const pam_handle_t *pamh,
- const struct pam_log_state *log_state,
- int priority, const char *format, va_list args)
-{
- const char *ident;
- int option, facility;
-
- D(("pam_vsystem_log called"));
+/* internal logging function */
- /* make sure we have a log state to use */
- if (NULL == log_state) {
- if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
- ident = pamh->pam_default_log.ident;
- option = pamh->pam_default_log.option;
- facility = pamh->pam_default_log.facility;
- } else {
- ident = PAM_LOG_STATE_IDENT;
- option = PAM_LOG_STATE_OPTION;
- facility = PAM_LOG_STATE_FACILITY;
- }
- openlog(ident, option, facility);
- } else {
- openlog(log_state->ident, log_state->option, log_state->facility);
- }
-
- vsyslog(priority, format, args);
- closelog();
-
- D(("done."));
-}
-
-void pam_system_log(const pam_handle_t *pamh,
- const struct pam_log_state *log_state,
- int priority, const char *format, ... )
+void _pam_system_log(int priority, const char *format, ... )
{
- const char *ident;
- int option, facility;
va_list args;
+ char *eformat;
D(("pam_system_log called"));
- /* make sure we have a log state to use */
- if (NULL == log_state) {
- if (NULL != pamh && NULL != pamh->pam_default_log.ident) {
- ident = pamh->pam_default_log.ident;
- option = pamh->pam_default_log.option;
- facility = pamh->pam_default_log.facility;
- } else {
- ident = PAM_LOG_STATE_IDENT;
- option = PAM_LOG_STATE_OPTION;
- facility = PAM_LOG_STATE_FACILITY;
- }
- openlog(ident, option, facility);
- } else {
- openlog(log_state->ident, log_state->option, log_state->facility);
+ if (format == NULL) {
+ D(("NULL format to _pam_system_log() call"));
+ return;
}
va_start(args, format);
- vsyslog(priority, format, args);
+
+ eformat = malloc(sizeof(_PAM_SYSTEM_LOG_PREFIX)+strlen(format));
+ if (eformat != NULL) {
+ strcpy(eformat, _PAM_SYSTEM_LOG_PREFIX);
+ strcpy(eformat + sizeof(_PAM_SYSTEM_LOG_PREFIX) - 1, format);
+ vsyslog(priority, eformat, args);
+ _pam_overwrite(eformat);
+ _pam_drop(eformat);
+ } else {
+ vsyslog(priority, format, args);
+ }
+
va_end(args);
- closelog();
D(("done."));
}
-/*
- * Recommended #defines to make porting legacy apps easier [Ed. at this
- * point, the syslog() #define is breoken -- suggestions?]
- *
- * #ifdef PAM_LOG_STATE
- * # define openlog(ident, option, facility) { \
- * struct pam_log_state tmp_state; \
- * tmp_state.ident = ident; \
- * tmp_state.option = option; \
- * tmp_state.facility = facility; \
- * (void) pam_set_item(pamh, PAM_LOG_STATE, &tmp_state); \
- * }
- * # define syslog pam_system_log
- * # define closelog()
- * #endif
- */
diff --git a/contrib/libpam/libpam/pam_malloc.c b/contrib/libpam/libpam/pam_malloc.c
index cc66f1aad6c7..d08a45611f90 100644
--- a/contrib/libpam/libpam/pam_malloc.c
+++ b/contrib/libpam/libpam/pam_malloc.c
@@ -1,13 +1,5 @@
/*
- * $Id: pam_malloc.c,v 1.2 1996/12/01 03:14:13 morgan Exp $
- *
- * $Log: pam_malloc.c,v $
- * Revision 1.2 1996/12/01 03:14:13 morgan
- * use _pam_macros.h
- *
- * Revision 1.1 1996/11/10 21:26:11 morgan
- * Initial revision
- *
+ * $Id: pam_malloc.c,v 1.3 2000/12/04 19:02:34 baggins Exp $
*/
/*
@@ -52,7 +44,7 @@
* default debugging level
*/
-int pam_malloc_flags = PAM_MALLOC_DEFAULT;
+int pam_malloc_flags = PAM_MALLOC_ALL;
int pam_malloc_delay_length = 4;
#define on(x) ((pam_malloc_flags&(x))==(x))
@@ -80,18 +72,27 @@ static void set_last_(const char *x, const char *f
static void _pam_output_xdebug_info(void)
{
FILE *logfile;
- int must_close = 1;
-
- if (!(logfile = fopen(_PAM_LOGFILE,"a"))) {
- logfile = stderr;
- must_close = 0;
+ int must_close = 1, fd;
+
+#ifdef O_NOFOLLOW
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_NOFOLLOW|O_APPEND)) != -1) {
+#else
+ if ((fd = open(_PAM_LOGFILE, O_WRONLY|O_APPEND)) != -1) {
+#endif
+ if (!(logfile = fdopen(fd,"a"))) {
+ logfile = stderr;
+ must_close = 0;
+ close(fd);
+ }
+ } else {
+ logfile = stderr;
+ must_close = 0;
}
fprintf(logfile, "[%s:%s(%d)->%s()] ",
last_file, last_call, last_line, last_fn);
- if (must_close) {
- fflush(logfile);
+ fflush(logfile);
+ if (must_close)
fclose(logfile);
- }
}
static void hinder(void)
diff --git a/contrib/libpam/libpam/pam_map.c b/contrib/libpam/libpam/pam_map.c
index 6e186b703bb0..86b16577dc86 100644
--- a/contrib/libpam/libpam/pam_map.c
+++ b/contrib/libpam/libpam/pam_map.c
@@ -1,11 +1,10 @@
/* pam_map.c - PAM mapping interface
*
- * $Id$
+ * $Id: pam_map.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* This is based on the X/Open XSSO specification of March 1997.
* It is not implemented as it is going to change... after 1997/9/25.
*
- * $Log$
*/
#include <stdio.h>
diff --git a/contrib/libpam/libpam/pam_misc.c b/contrib/libpam/libpam/pam_misc.c
index 6fed9ba126b9..6c1d5d62343c 100644
--- a/contrib/libpam/libpam/pam_misc.c
+++ b/contrib/libpam/libpam/pam_misc.c
@@ -1,35 +1,7 @@
/* pam_misc.c -- This is random stuff */
-/* $Id: pam_misc.c,v 1.9 1997/04/05 06:56:19 morgan Exp $
- *
- * $Log: pam_misc.c,v $
- * Revision 1.9 1997/04/05 06:56:19 morgan
- * enforce AUTHTOK restrictions
- *
- * Revision 1.8 1997/02/15 15:59:46 morgan
- * modified ..strCMP comment
- *
- * Revision 1.7 1996/12/01 03:14:13 morgan
- * use _pam_macros.h
- *
- * Revision 1.6 1996/11/10 20:05:52 morgan
- * name convention _pam_ enforced. Also modified _pam_strdup()
- *
- * Revision 1.5 1996/07/07 23:57:14 morgan
- * deleted debuggin function and replaced it with a static function
- * defined in pam_private.h
- *
- * Revision 1.4 1996/06/02 08:00:56 morgan
- * added StrTok function
- *
- * Revision 1.3 1996/05/21 04:36:58 morgan
- * added debugging information
- * replaced the _pam_log need for a local buffer with a call to vsyslog()
- * [Al Longyear had some segfaulting problems related to this]
- *
- * Revision 1.2 1996/03/16 21:55:13 morgan
- * changed pam_mkargv to _pam_mkargv
- *
+/*
+ * $Id: pam_misc.c,v 1.2 2001/01/22 06:07:29 agmorgan Exp $
*/
#include <stdarg.h>
@@ -125,8 +97,7 @@ char *_pam_strdup(const char *x)
for (i=0; x[i]; ++i); /* length of string */
if ((new = malloc(++i)) == NULL) {
i = 0;
- pam_system_log(NULL, NULL, LOG_CRIT,
- "_pam_strdup: failed to get memory");
+ _pam_system_log(LOG_CRIT, "_pam_strdup: failed to get memory");
} else {
while (i-- > 0) {
new[i] = x[i];
@@ -160,15 +131,15 @@ int _pam_mkargv(char *s, char ***argv, int *argc)
l = strlen(s);
if (l) {
if ((sbuf = sbuf_start = _pam_strdup(s)) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_mkargv: null returned by _pam_strdup");
+ _pam_system_log(LOG_CRIT,
+ "pam_mkargv: null returned by _pam_strdup");
D(("arg NULL"));
} else {
/* Overkill on the malloc, but not large */
argvlen = (l + 1) * ((sizeof(char)) + sizeof(char *));
if ((our_argv = argvbuf = malloc(argvlen)) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_mkargv: null returned by malloc");
+ _pam_system_log(LOG_CRIT,
+ "pam_mkargv: null returned by malloc");
} else {
char *tmp=NULL;
@@ -206,11 +177,15 @@ int _pam_mkargv(char *s, char ***argv, int *argc)
void _pam_sanitize(pam_handle_t *pamh)
{
+ int old_caller_is = pamh->caller_is;
+
/*
* this is for security. We reset the auth-tokens here.
*/
- pam_set_item(pamh,PAM_AUTHTOK,NULL);
- pam_set_item(pamh,PAM_OLDAUTHTOK,NULL);
+ __PAM_TO_MODULE(pamh);
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
+ pam_set_item(pamh, PAM_OLDAUTHTOK, NULL);
+ pamh->caller_is = old_caller_is;
}
/*
@@ -247,7 +222,7 @@ void _pam_parse_control(int *control_array, char *tok)
int act, len;
/* skip leading space */
- while (isspace(*tok) && *++tok);
+ while (isspace((int)*tok) && *++tok);
if (!*tok)
break;
@@ -264,21 +239,21 @@ void _pam_parse_control(int *control_array, char *tok)
}
/* observe '=' */
- while (isspace(*tok) && *++tok);
+ while (isspace((int)*tok) && *++tok);
if (!*tok || *tok++ != '=') {
error = "expecting '='";
goto parse_error;
}
/* skip leading space */
- while (isspace(*tok) && *++tok);
+ while (isspace((int)*tok) && *++tok);
if (!*tok) {
error = "expecting action";
goto parse_error;
}
/* observe action type */
- for (act=0; act<=-_PAM_ACTION_UNDEF; ++act) {
+ for (act=0; act < (-(_PAM_ACTION_UNDEF)); ++act) {
len = strlen(_pam_token_actions[act]);
if (!strncmp(_pam_token_actions[act], tok, len)) {
act *= -1;
@@ -296,7 +271,7 @@ void _pam_parse_control(int *control_array, char *tok)
* cause looping problems. So, for now, we will just
* allow forward jumps. (AGM 1998/1/7)
*/
- if (!isdigit(*tok)) {
+ if (!isdigit((int)*tok)) {
error = "expecting jump number";
goto parse_error;
}
@@ -305,7 +280,7 @@ void _pam_parse_control(int *control_array, char *tok)
do {
act *= 10;
act += *tok - '0'; /* XXX - this assumes ascii behavior */
- } while (*++tok && isdigit(*tok));
+ } while (*++tok && isdigit((int)*tok));
if (! act) {
/* we do not allow 0 jumps. There is a token ('ignore')
for that */
@@ -328,7 +303,7 @@ void _pam_parse_control(int *control_array, char *tok)
parse_error:
/* treat everything as bad */
- pam_system_log(NULL, NULL, LOG_ERR, "pam_parse: %s; [...%s]", error, tok);
+ _pam_system_log(LOG_ERR, "pam_parse: %s; [...%s]", error, tok);
for (ret=0; ret<_PAM_RETURN_VALUES; control_array[ret++]=_PAM_ACTION_BAD);
}
diff --git a/contrib/libpam/libpam/pam_password.c b/contrib/libpam/libpam/pam_password.c
index 303425ab6254..c247b1269f79 100644
--- a/contrib/libpam/libpam/pam_password.c
+++ b/contrib/libpam/libpam/pam_password.c
@@ -1,14 +1,14 @@
/* pam_password.c - PAM Password Management */
/*
- * $Id: pam_password.c,v 1.7 1997/04/05 06:56:45 morgan Exp $
- *
- * $Log: pam_password.c,v $
+ * $Id: pam_password.c,v 1.2 2001/01/22 06:07:29 agmorgan Exp $
*/
#include <stdio.h>
#include <stdlib.h>
+/* #define DEBUG */
+
#include "pam_private.h"
int pam_chauthtok(pam_handle_t *pamh, int flags)
@@ -19,6 +19,11 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
IF_NO_PAMH("pam_chauthtok", pamh, PAM_SYSTEM_ERR);
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
+
if (pamh->former.choice == PAM_NOT_STACKED) {
_pam_start_timer(pamh); /* we try to make the time for a failure
independent of the time it takes to
@@ -27,10 +32,11 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
pamh->former.update = PAM_FALSE;
}
- /* first loop through to check if there will be a problem */
+ /* first call to check if there will be a problem */
if (pamh->former.update ||
(retval = _pam_dispatch(pamh, flags|PAM_PRELIM_CHECK,
PAM_CHAUTHTOK)) == PAM_SUCCESS) {
+ D(("completed check ok: former=%d", pamh->former.update));
pamh->former.update = PAM_TRUE;
retval = _pam_dispatch(pamh, flags|PAM_UPDATE_AUTHTOK,
PAM_CHAUTHTOK);
@@ -41,9 +47,9 @@ int pam_chauthtok(pam_handle_t *pamh, int flags)
_pam_sanitize(pamh);
pamh->former.update = PAM_FALSE;
_pam_await_timer(pamh, retval); /* if unsuccessful then wait now */
- D(("pam_authenticate exit"));
+ D(("pam_chauthtok exit %d - %d", retval, pamh->former.choice));
} else {
- D(("will resume when ready"));
+ D(("will resume when ready", retval));
}
return retval;
diff --git a/contrib/libpam/libpam/pam_private.h b/contrib/libpam/libpam/pam_private.h
index f8a0da54fc94..cd7843f92dcc 100644
--- a/contrib/libpam/libpam/pam_private.h
+++ b/contrib/libpam/libpam/pam_private.h
@@ -1,7 +1,7 @@
/*
* pam_private.h
*
- * $Id: pam_private.h,v 1.12 1997/04/05 06:57:37 morgan Exp morgan $
+ * $Id: pam_private.h,v 1.4 2001/02/05 06:50:41 agmorgan Exp $
*
* This is the Linux-PAM Library Private Header. It contains things
* internal to the Linux-PAM library. Things not needed by either an
@@ -10,16 +10,16 @@
* Please see end of file for copyright.
*
* Creator: Marc Ewing.
- * Maintained: AGM
- *
- * $Log: pam_private.h,v $
+ * Maintained: CVS
*/
#ifndef _PAM_PRIVATE_H
#define _PAM_PRIVATE_H
+#include <security/_pam_aconf.h>
+
/* this is not used at the moment --- AGM */
-#define LIBPAM_VERSION 65
+#define LIBPAM_VERSION (LIBPAM_VERSION_MAJOR*0x100 + LIBPAM_VERSION_MINOR)
#include <security/pam_appl.h>
#include <security/pam_modules.h>
@@ -47,6 +47,9 @@ struct handler {
int must_fail;
int (*func)(pam_handle_t *pamh, int flags, int argc, char **argv);
int actions[_PAM_RETURN_VALUES];
+ /* set by authenticate, open_session, chauthtok(1st)
+ consumed by setcred, close_session, chauthtok(2nd) */
+ int cached_retval; int *cached_retval_p;
int argc;
char **argv;
struct handler *next;
@@ -126,6 +129,7 @@ struct _pam_former_state {
struct pam_handle {
char *authtok;
+ unsigned caller_is;
struct pam_conv *pam_conversation;
char *oldauthtok;
char *prompt; /* for use by pam_get_user() */
@@ -134,7 +138,6 @@ struct pam_handle {
char *rhost;
char *ruser;
char *tty;
- struct pam_log_state pam_default_log; /* for ident etc., log state */
struct pam_data *data;
struct pam_environ *env; /* structure to maintain environment list */
struct _pam_fail_delay fail_delay; /* helper function for easy delays */
@@ -191,8 +194,6 @@ int _pam_make_env(pam_handle_t *pamh);
/* delete the environment structure */
void _pam_drop_env(pam_handle_t *pamh);
-#ifdef LINUX_PAM
-
/* these functions deal with failure delays as required by the
authentication modules and application. Their *interface* is likely
to remain the same although their function is hopefully going to
@@ -207,16 +208,13 @@ void _pam_start_timer(pam_handle_t *pamh);
/* this waits for the clock to stop ticking if status != PAM_SUCCESS */
void _pam_await_timer(pam_handle_t *pamh, int status);
-
-#endif /* LINUX_PAM */
-
typedef void (*voidfunc(void))(void);
#ifdef PAM_STATIC
/* The next two in ../modules/_pam_static/pam_static.c */
/* Return pointer to data structure used to define a static module */
-struct pam_module * _pam_open_static_handler(char *path);
+struct pam_module * _pam_open_static_handler(const char *path);
/* Return pointer to function requested from static module */
@@ -250,6 +248,9 @@ void _pam_set_default_control(int *control_array, int default_action);
void _pam_parse_control(int *control_array, char *tok);
+void _pam_system_log(int priority, const char *format, ... );
+#define _PAM_SYSTEM_LOG_PREFIX "PAM "
+
/*
* XXX - Take care with this. It could confuse the logic of a trailing
* else
@@ -257,7 +258,7 @@ void _pam_parse_control(int *control_array, char *tok);
#define IF_NO_PAMH(X,pamh,ERR) \
if ((pamh) == NULL) { \
- pam_system_log(NULL, NULL, LOG_ERR, X ": NULL pam handle passed"); \
+ _pam_system_log(LOG_ERR, X ": NULL pam handle passed"); \
return ERR; \
}
@@ -266,24 +267,27 @@ if ((pamh) == NULL) { \
#define PAM_DEFAULT_PROMPT "Please enter username: "
/*
- * pam_system_log default ident/facility..
- */
-
-#define PAM_LOG_STATE_DEFAULT { \
- PAM_LOG_STATE_IDENT, \
- PAM_LOG_STATE_OPTION, \
- PAM_LOG_STATE_FACILITY \
-}
-
-/*
* include some helpful macros
*/
#include <security/_pam_macros.h>
+/* used to work out where control currently resides (in an application
+ or in a module) */
+
+#define _PAM_CALLED_FROM_MODULE 1
+#define _PAM_CALLED_FROM_APP 2
+
+#define __PAM_FROM_MODULE(pamh) ((pamh)->caller_is == _PAM_CALLED_FROM_MODULE)
+#define __PAM_FROM_APP(pamh) ((pamh)->caller_is == _PAM_CALLED_FROM_APP)
+#define __PAM_TO_MODULE(pamh) \
+ do { (pamh)->caller_is = _PAM_CALLED_FROM_MODULE; } while (0)
+#define __PAM_TO_APP(pamh) \
+ do { (pamh)->caller_is = _PAM_CALLED_FROM_APP; } while (0)
+
/*
* Copyright (C) 1995 by Red Hat Software, Marc Ewing
- * Copyright (c) 1996-8, Andrew G. Morgan <morgan@linux.kernel.org>
+ * Copyright (c) 1996-8,2001 by Andrew G. Morgan <morgan@kernel.org>
*
* All rights reserved
*
diff --git a/contrib/libpam/libpam/pam_second.c b/contrib/libpam/libpam/pam_second.c
index b720774e7e61..72bd7ea5ddcd 100644
--- a/contrib/libpam/libpam/pam_second.c
+++ b/contrib/libpam/libpam/pam_second.c
@@ -2,9 +2,8 @@
* pam_second.c -- PAM secondary authentication
* (based on XSSO draft spec of March 1997)
*
- * $Id$
+ * $Id: pam_second.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
- * $Log$
*/
#include <stdio.h>
diff --git a/contrib/libpam/libpam/pam_session.c b/contrib/libpam/libpam/pam_session.c
index 38b93fe70549..3709f62d77ae 100644
--- a/contrib/libpam/libpam/pam_session.c
+++ b/contrib/libpam/libpam/pam_session.c
@@ -1,17 +1,7 @@
/* pam_session.c - PAM Session Management */
/*
- * $Id: pam_session.c,v 1.3 1996/12/01 03:14:13 morgan Exp $
- *
- * $Log: pam_session.c,v $
- * Revision 1.3 1996/12/01 03:14:13 morgan
- * use _pam_macros.h
- *
- * Revision 1.2 1996/03/10 02:19:12 morgan
- * some oversight meant that this wasn't being compiled. It needed a
- * couple of changes.
- *
- *
+ * $Id: pam_session.c,v 1.3 2001/01/22 06:07:29 agmorgan Exp $
*/
#include <stdio.h>
@@ -22,7 +12,13 @@ int pam_open_session(pam_handle_t *pamh, int flags)
{
D(("called"));
- IF_NO_PAMH("pam_open_session",pamh,PAM_SYSTEM_ERR);
+ IF_NO_PAMH("pam_open_session", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
+
return _pam_dispatch(pamh, flags, PAM_OPEN_SESSION);
}
@@ -30,6 +26,12 @@ int pam_close_session(pam_handle_t *pamh, int flags)
{
D(("called"));
- IF_NO_PAMH("pam_close_session",pamh,PAM_SYSTEM_ERR);
+ IF_NO_PAMH("pam_close_session", pamh, PAM_SYSTEM_ERR);
+
+ if (__PAM_FROM_MODULE(pamh)) {
+ D(("called from module!?"));
+ return PAM_SYSTEM_ERR;
+ }
+
return _pam_dispatch(pamh, flags, PAM_CLOSE_SESSION);
}
diff --git a/contrib/libpam/libpam/pam_start.c b/contrib/libpam/libpam/pam_start.c
index 53700a091029..2296c9a95001 100644
--- a/contrib/libpam/libpam/pam_start.c
+++ b/contrib/libpam/libpam/pam_start.c
@@ -3,9 +3,8 @@
/* Creator Marc Ewing
* Maintained by AGM
*
- * $Id: pam_start.c,v 1.10 1997/04/05 06:58:11 morgan Exp $
+ * $Id: pam_start.c,v 1.2 2001/01/22 06:07:29 agmorgan Exp $
*
- * $Log: pam_start.c,v $
*/
#include <ctype.h>
@@ -26,17 +25,21 @@ int pam_start (
,service_name, user, pam_conversation, pamh));
if ((*pamh = calloc(1, sizeof(**pamh))) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_start: calloc failed for *pamh");
+ _pam_system_log(LOG_CRIT, "pam_start: calloc failed for *pamh");
return (PAM_BUF_ERR);
}
+ /* Mark the caller as the application - permission to do certain
+ things is limited to a module or an application */
+
+ __PAM_TO_APP(*pamh);
+
if (service_name) {
char *tmp;
if (((*pamh)->service_name = _pam_strdup(service_name)) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_start: _pam_strdup failed for service name");
+ _pam_system_log(LOG_CRIT,
+ "pam_start: _pam_strdup failed for service name");
_pam_drop(*pamh);
return (PAM_BUF_ERR);
}
@@ -47,8 +50,8 @@ int pam_start (
if (user) {
if (((*pamh)->user = _pam_strdup(user)) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_start: _pam_strdup failed for user");
+ _pam_system_log(LOG_CRIT,
+ "pam_start: _pam_strdup failed for user");
_pam_drop((*pamh)->service_name);
_pam_drop(*pamh);
return (PAM_BUF_ERR);
@@ -68,8 +71,7 @@ int pam_start (
if (pam_conversation == NULL
|| ((*pamh)->pam_conversation = (struct pam_conv *)
malloc(sizeof(struct pam_conv))) == NULL) {
- pam_system_log(NULL, NULL, LOG_CRIT,
- "pam_start: malloc failed for pam_conv");
+ _pam_system_log(LOG_CRIT, "pam_start: malloc failed for pam_conv");
_pam_drop((*pamh)->service_name);
_pam_drop((*pamh)->user);
_pam_drop(*pamh);
@@ -81,8 +83,7 @@ int pam_start (
(*pamh)->data = NULL;
if ( _pam_make_env(*pamh) != PAM_SUCCESS ) {
- pam_system_log(NULL, NULL, LOG_ERR,
- "pam_start: failed to initialize environment");
+ _pam_system_log(LOG_ERR,"pam_start: failed to initialize environment");
_pam_drop((*pamh)->service_name);
_pam_drop((*pamh)->user);
_pam_drop(*pamh);
@@ -96,21 +97,15 @@ int pam_start (
/* According to the SunOS man pages, loading modules and resolving
* symbols happens on the first call from the application. */
- /*
- * XXX - should we call _pam_init_handlers() here ? The following
- * is new as of Linux-PAM 0.55
- */
-
if ( _pam_init_handlers(*pamh) != PAM_SUCCESS ) {
- pam_system_log(NULL, NULL, LOG_ERR,
- "pam_start: failed to initialize handlers");
+ _pam_system_log(LOG_ERR, "pam_start: failed to initialize handlers");
_pam_drop_env(*pamh); /* purge the environment */
_pam_drop((*pamh)->service_name);
_pam_drop((*pamh)->user);
_pam_drop(*pamh);
return PAM_ABORT;
}
-
+
D(("exiting pam_start successfully"));
return PAM_SUCCESS;
diff --git a/contrib/libpam/libpam/pam_static.c b/contrib/libpam/libpam/pam_static.c
index d840a2dc6d2c..5a2b5a5d265e 100644
--- a/contrib/libpam/libpam/pam_static.c
+++ b/contrib/libpam/libpam/pam_static.c
@@ -2,21 +2,7 @@
/* created by Michael K. Johnson, johnsonm@redhat.com
*
- * $Id: pam_static.c,v 1.4 1996/12/01 03:14:13 morgan Exp $
- *
- * $Log: pam_static.c,v $
- * Revision 1.4 1996/12/01 03:14:13 morgan
- * use _pam_macros.h
- *
- * Revision 1.3 1996/11/10 20:09:16 morgan
- * name convention change _pam_
- *
- * Revision 1.2 1996/06/02 08:02:56 morgan
- * Michael's minor alterations
- *
- * Revision 1.1 1996/05/26 04:34:04 morgan
- * Initial revision
- *
+ * $Id: pam_static.c,v 1.1.1.1 2000/06/20 22:11:21 agmorgan Exp $
*/
/* This whole file is only used for PAM_STATIC */
@@ -53,16 +39,18 @@ static struct pam_module *static_modules[] = {
*/
/* Return pointer to data structure used to define a static module */
-struct pam_module * _pam_open_static_handler(char *path) {
+struct pam_module * _pam_open_static_handler(const char *path)
+{
int i;
- char *lpath = path, *end;
+ const char *clpath = path;
+ char *lpath, *end;
- if (strchr(lpath, '/')) {
+ if (strchr(clpath, '/')) {
/* ignore path and leading "/" */
- lpath = strrchr(lpath, '/') + 1;
+ clpath = strrchr(lpath, '/') + 1;
}
/* create copy to muck with (must free before return) */
- lpath = _pam_strdup(lpath);
+ lpath = _pam_strdup(clpath);
/* chop .so off copy if it exists (or other extension on other
platform...) */
end = strstr(lpath, ".so");
@@ -80,8 +68,8 @@ struct pam_module * _pam_open_static_handler(char *path) {
}
if (static_modules[i] == NULL) {
- pam_system_log(pamh, NULL, LOG_ERR, "no static module named %s",
- lpath);
+ _pam_system_log(NULL, NULL, LOG_ERR, "no static module named %s",
+ lpath);
}
free(lpath);
diff --git a/contrib/libpam/libpam/pam_strerror.c b/contrib/libpam/libpam/pam_strerror.c
index 607c6d5dbfef..4f2249db75de 100644
--- a/contrib/libpam/libpam/pam_strerror.c
+++ b/contrib/libpam/libpam/pam_strerror.c
@@ -1,20 +1,7 @@
/* pam_strerror.c */
-/* $Id: pam_strerror.c,v 1.6 1997/01/04 20:12:02 morgan Exp morgan $
- *
- * $Log: pam_strerror.c,v $
- * Revision 1.6 1997/01/04 20:12:02 morgan
- * replaced conditional FAIL_NOW with ABORT
- *
- * Revision 1.5 1996/07/07 23:58:56 morgan
- * corrected "... " to "..."
- *
- * Revision 1.4 1996/06/02 08:03:29 morgan
- * spelling correction
- *
- * Revision 1.3 1996/03/16 23:08:54 morgan
- * PAM --> Linux-PAM ;)
- *
+/*
+ * $Id: pam_strerror.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*/
#include "pam_private.h"
diff --git a/contrib/libpam/libpam/pam_tokens.h b/contrib/libpam/libpam/pam_tokens.h
index 9380f8837b96..69e794895ecc 100644
--- a/contrib/libpam/libpam/pam_tokens.h
+++ b/contrib/libpam/libpam/pam_tokens.h
@@ -1,7 +1,7 @@
/*
* pam_tokens.h
*
- * $Id$
+ * $Id: pam_tokens.h,v 1.3 2001/01/22 06:07:29 agmorgan Exp $
*
* This is a Linux-PAM Library Private Header file. It contains tokens
* that are used when we parse the configuration file(s).
@@ -9,8 +9,7 @@
* Please see end of file for copyright.
*
* Creator: Andrew Morgan.
- *
- * $Log$
+ *
*/
#ifndef _PAM_TOKENS_H
@@ -60,13 +59,15 @@ const char * const _pam_token_returns[_PAM_RETURN_VALUES+1] = {
"authtok_expired", /* 27 */
"module_unknown", /* 28 */
"bad_item", /* 29 */
+ "conv_again", /* 30 */
+ "incomplete", /* 31 */
/* add new return codes here */
"default" /* this is _PAM_RETURN_VALUES and indicates
the default return action */
};
/*
- * Copyright (C) 1998, Andrew G. Morgan <morgan@linux.kernel.org>
+ * Copyright (C) 1998,2001 Andrew G. Morgan <morgan@kernel.org>
*
* All rights reserved
*
diff --git a/contrib/libpam/libpam_misc/Makefile b/contrib/libpam/libpam_misc/Makefile
index 1cfc86577b1f..b7ff178cbe7d 100644
--- a/contrib/libpam/libpam_misc/Makefile
+++ b/contrib/libpam/libpam_misc/Makefile
@@ -1,109 +1,106 @@
-# $Header: /home/morgan/pam/Linux-PAM-0.57/libpam_misc/RCS/Makefile,v 1.10 1997/04/05 07:00:18 morgan Exp $
#
-# $Log: Makefile,v $
-# Revision 1.10 1997/04/05 07:00:18 morgan
-# fakeroot
-#
-# Revision 1.9 1997/02/15 15:46:56 morgan
-# inherit major and minor numbers from top level
-#
-# Revision 1.8 1997/01/04 20:20:11 morgan
-# update for .55 and make -> $(MAKE)
-#
-# Revision 1.7 1996/12/01 03:28:11 morgan
-# update for 0.54
+# $Id: Makefile,v 1.3 2001/02/10 07:17:53 agmorgan Exp $
#
-dummy:
- @echo "*** This is not a top-level Makefile!"
+# lots of debugging information goes to /tmp/pam-debug.log
+#MOREFLAGS += -D"DEBUG"
-# ///////////////////////////////////////////////////////////////////
+include ../Make.Rules
-# uncomment if you wnat libpam_misc to be made as a dynamic library
-# AGM has had some segfaulting from libdl when I did this. I have not
-# investigated the cause...
-
-MAKE_DYNAMIC=yes
-
-ifeq ($(DEBUG_REL),yes)
- LIBNAME=pamd_misc
+ifeq ($(WITH_LIBDEBUG),yes)
+ LIBNAME=libpam_miscd
else
- LIBNAME=pam_misc
+ LIBNAME=libpam_misc
endif
-LIBMAJOR=$(MAJOR_REL)
-LIBMINOR=$(MINOR_REL)
-
-FILES=misc_conv help_env
+VERSION=.$(MAJOR_REL)
+MODIFICATION=.$(MINOR_REL)
-#
-# Probably no need to alter anything below here.
-#
+CFLAGS += $(MOREFLAGS) $(DYNAMIC) $(STATIC)
-# build dynamic library names
+# dynamic library names
-LIBDYNAMIC=lib$(LIBNAME).$(DYNTYPE)
-LIBDYNMAJ=$(LIBDYNAMIC).$(LIBMAJOR)
-LIBDYNMIN=$(LIBDYNMAJ).$(LIBMINOR)
+LIBNAMED = $(LIBNAME).$(DYNTYPE)
+LIBNAMEDNAME = $(LIBNAMED)$(VERSION)
+LIBNAMEDFULL = $(LIBNAMEDNAME)$(MODIFICATION)
# static library name
-LIBSTATIC = lib$(LIBNAME).a
+LIBNAMEDSTATIC = $(LIBNAME).a
+
+LIBOBJECTS = help_env.o misc_conv.o
-# sources and object files
+ifeq ($(DYNAMIC_LIBPAM),yes)
+DLIBOBJECTS = $(addprefix dynamic/,$(LIBOBJECTS))
+endif
-LIBSRC = $(addsuffix .c,$(FILES))
-LIBOBJ = $(addsuffix .o,$(FILES))
+ifeq ($(STATIC_LIBPAM),yes)
+SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS))
+endif
-# rules
+# ---------------------------------------------
+## rules
-all: $(LIBSTATIC) $(LIBDYNAMIC)
+all: dirs $(LIBNAMED) $(LIBNAMEDSTATIC)
-$(LIBDYNAMIC): $(LIBOBJ)
-ifdef MAKE_DYNAMIC
+dirs:
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(MKDIR) dynamic
+endif
+ifeq ($(STATIC_LIBPAM),yes)
+ $(MKDIR) static
+endif
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+static/%.o : %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+$(LIBNAMED): $(DLIBOBJECTS)
+ifeq ($(DYNAMIC_LIBPAM),yes)
ifeq ($(USESONAME),yes)
- $(LD_L) $(SOSWITCH) $(LIBDYNMAJ) -o $@ $(LIBOBJ)
+ $(LD_L) $(SOSWITCH) $(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
else
- $(LD_L) -o $@ $(LIBOBJ)
+ $(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
endif
ifeq ($(NEEDSONAME),yes)
- rm -f $(LIBDYNMIN)
- ln -s $(LIBDYNAMIC) $(LIBDYNMAJ)
- rm -f $(LIBDYNMAJ)
- ln -s $(LIBDYNAMIC) $(LIBDYNMIN)
+ rm -f $(LIBNAMEDFULL)
+ ln -s $(LIBNAMED) $(LIBNAMEDFULL)
+ rm -f $(LIBNAMEDNAME)
+ ln -s $(LIBNAMED) $(LIBNAMEDNAME)
endif
endif
-$(LIBSTATIC): $(LIBOBJ)
- $(AR) $@ $(LIBOBJ)
+$(LIBNAMEDSTATIC): $(SLIBOBJECTS)
+ifeq ($(STATIC_LIBPAM),yes)
+ $(AR) rc $@ $(SLIBOBJECTS) $(MODULES)
$(RANLIB) $@
+endif
install: all
$(MKDIR) $(FAKEROOT)$(INCLUDED)
- $(INSTALL) -m 644 ./pam_misc.h $(FAKEROOT)$(INCLUDED)
-ifdef MAKE_DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBDYNAMIC) $(FAKEROOT)$(LIBDIR)/$(LIBDYNMIN)
+ $(INSTALL) -m 644 include/security/pam_misc.h $(FAKEROOT)$(INCLUDED)
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(MKDIR) $(FAKEROOT)$(libdir)
+ $(INSTALL) -m $(SHLIBMODE) $(LIBNAMED) $(FAKEROOT)$(libdir)/$(LIBNAMEDFULL)
$(LDCONFIG)
ifneq ($(DYNTYPE),"sl")
- ( cd $(FAKEROOT)$(LIBDIR) ; ln -sf $(LIBDYNMAJ) $(LIBDYNAMIC) )
+ ( cd $(FAKEROOT)$(libdir) ; rm -f $(LIBNAMED) ; ln -s $(LIBNAMEDNAME) $(LIBNAMED) )
endif
endif
- $(INSTALL) -m 644 $(LIBSTATIC) $(FAKEROOT)$(LIBDIR)
-
-clean:
- rm -f *.so *.a core a.out *~
+ifeq ($(STATIC_LIBPAM),yes)
+ $(INSTALL) -m 644 $(LIBNAMEDSTATIC) $(FAKEROOT)$(libdir)
+endif
remove:
rm -f $(FAKEROOT)$(INCLUDED)/pam_misc.h
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBDYNAMIC).*
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBDYNAMIC)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMEDFULL)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMED)
$(LDCONFIG)
- rm -f $(FAKEROOT)$(LIBDIR)/$(LIBSTATIC)
- rm -f $(FAKEROOT)$(INCLUDED)/chk_malloc.h
-
-.c.o:
- $(CC) -c $(DEFS) $(CFLAGS) $<
-
-extraclean:
- @$(MAKE) clean
- rm -f *.o *.bak
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMEDSTATIC)
+clean:
+ rm -f a.out core *~ static/*.o dynamic/*.o
+ rm -f *.a *.out *.o *.so ./include/security/*~
+ if [ -d dynamic ]; then rmdir dynamic ; fi
+ if [ -d static ]; then rmdir static ; fi
diff --git a/contrib/libpam/libpam_misc/help_env.c b/contrib/libpam/libpam_misc/help_env.c
index d35b66b948ca..e1390984273c 100644
--- a/contrib/libpam/libpam_misc/help_env.c
+++ b/contrib/libpam/libpam_misc/help_env.c
@@ -1,15 +1,8 @@
/*
- * $Id: help_env.c,v 1.2 1997/01/04 20:19:20 morgan Exp morgan $
+ * $Id: help_env.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* This file was written by Andrew G. Morgan <morgan@parc.power.net>
*
- * $Log: help_env.c,v $
- * Revision 1.2 1997/01/04 20:19:20 morgan
- * added a prototype (no warning) and fixed paste function
- *
- * Revision 1.1 1996/12/01 03:25:37 morgan
- * Initial revision
- *
*/
#include <stdlib.h>
diff --git a/contrib/libpam/libpam_misc/include/security/pam_misc.h b/contrib/libpam/libpam_misc/include/security/pam_misc.h
new file mode 100644
index 000000000000..1e8c4784c532
--- /dev/null
+++ b/contrib/libpam/libpam_misc/include/security/pam_misc.h
@@ -0,0 +1,57 @@
+/* $Id: pam_misc.h,v 1.3 2001/01/20 22:29:47 agmorgan Exp $ */
+
+#ifndef __PAMMISC_H
+#define __PAMMISC_H
+
+#include <security/pam_appl.h>
+#include <security/pam_client.h>
+
+/* include some useful macros */
+
+#include <security/_pam_macros.h>
+
+/* functions defined in pam_misc.* libraries */
+
+extern int misc_conv(int num_msg, const struct pam_message **msgm,
+ struct pam_response **response, void *appdata_ptr);
+
+#include <time.h>
+
+extern time_t pam_misc_conv_warn_time; /* time that we should warn user */
+extern time_t pam_misc_conv_die_time; /* cut-off time for input */
+extern const char *pam_misc_conv_warn_line; /* warning notice */
+extern const char *pam_misc_conv_die_line; /* cut-off remark */
+extern int pam_misc_conv_died; /* 1 = cut-off time reached (0 not) */
+extern int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t *prompt_p);
+extern void (*pam_binary_handler_free)(void *appdata, pamc_bp_t *prompt_p);
+/*
+ * Environment helper functions
+ */
+
+/* transcribe given environment (to pam) */
+extern int pam_misc_paste_env(pam_handle_t *pamh
+ , const char * const * user_env);
+
+/* char **pam_misc_copy_env(pam_handle_t *pamh);
+
+ This is no longer defined as a prototype because the X/Open XSSO
+ spec makes it clear that PAM's pam_getenvlist() does exactly
+ what this was needed for.
+
+ A wrapper is still provided in the pam_misc library - so that
+ legacy applications will still work. But _BE_WARNED_ it will
+ disappear by the release of libpam 1.0 . */
+
+/* delete environment as obtained from (pam_getenvlist) */
+extern char **pam_misc_drop_env(char **env);
+
+/* provide something like the POSIX setenv function for the (Linux-)PAM
+ * environment. */
+
+extern int pam_misc_setenv(pam_handle_t *pamh, const char *name
+ , const char *value, int readonly);
+
+#endif
+
+
+
diff --git a/contrib/libpam/libpam_misc/misc_conv.c b/contrib/libpam/libpam_misc/misc_conv.c
index 53cf51b76ccc..8e2460dc4c13 100644
--- a/contrib/libpam/libpam_misc/misc_conv.c
+++ b/contrib/libpam/libpam_misc/misc_conv.c
@@ -1,32 +1,12 @@
/*
- * $Id: misc_conv.c,v 1.5 1997/01/04 20:16:48 morgan Exp morgan $
+ * $Id: misc_conv.c,v 1.3 2001/01/20 22:29:47 agmorgan Exp $
*
* A generic conversation function for text based applications
*
* Written by Andrew Morgan <morgan@linux.kernel.org>
- *
- * $Log: misc_conv.c,v $
- * Revision 1.5 1997/01/04 20:16:48 morgan
- * removed getpass. Replaced with POSIX code for same function which
- * also observes timeouts specified by the parent application
- *
- * Revision 1.4 1996/12/01 03:26:51 morgan
- * *** empty log message ***
- *
- * Revision 1.3 1996/11/10 20:10:01 morgan
- * sgi definition
- *
- * Revision 1.2 1996/07/07 23:59:56 morgan
- * changed the name of the misc include file
- *
- * Revision 1.1 1996/05/02 05:17:06 morgan
- * Initial revision
*/
-#ifdef linux
-#define _GNU_SOURCE
-#include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <signal.h>
#include <stdio.h>
@@ -57,39 +37,23 @@ const char *pam_misc_conv_die_line = "..\a.Sorry, your time is up!\n";
int pam_misc_conv_died=0; /* application can probe this for timeout */
-static void pam_misc_conv_delete_binary(void **delete_me)
+/*
+ * These functions are for binary prompt manipulation.
+ * The manner in which a binary prompt is processed is application
+ * specific, so these function pointers are provided and can be
+ * initialized by the application prior to the conversation function
+ * being used.
+ */
+
+static void pam_misc_conv_delete_binary(void *appdata,
+ pamc_bp_t *delete_me)
{
- if (delete_me && *delete_me) {
- unsigned char *packet = *(unsigned char **)delete_me;
- int length;
-
- length = 4+(packet[0]<<24)+(packet[1]<<16)+(packet[2]<<8)+packet[3];
- memset(packet, 0, length);
- free(packet);
- *delete_me = packet = NULL;
- }
+ PAM_BP_RENEW(delete_me, 0, 0);
}
-/* These function pointers are for application specific binary
- conversations. One or both of the arguments to the first function
- must be non-NULL. The first function must return PAM_SUCCESS or
- PAM_CONV_ERR. If input is non-NULL, a response is expected, this
- response should be malloc()'d and will eventually be free()'d by
- the calling module. The structure of this malloc()'d response is as
- follows:
-
- { int length, char data[length] }
-
- For convenience, the pointer used by the two function pointer
- prototypes is 'void *'.
-
- The ...free() fn pointer is used to discard a binary message that
- is not of the default form. It should be explicitly overwritten
- when using some other convention for the structure of a binary
- prompt (not recommended). */
-
-int (*pam_binary_handler_fn)(const void *send, void **receive) = NULL;
-void (*pam_binary_handler_free)(void **packet_p) = pam_misc_conv_delete_binary;
+int (*pam_binary_handler_fn)(void *appdata, pamc_bp_t *prompt_p) = NULL;
+void (*pam_binary_handler_free)(void *appdata, pamc_bp_t *prompt_p)
+ = pam_misc_conv_delete_binary;
/* the following code is used to get text input */
@@ -293,26 +257,26 @@ int misc_conv(int num_msg, const struct pam_message **msgm,
break;
case PAM_BINARY_PROMPT:
{
- void *pack_out=NULL;
- const void *pack_in = msgm[count]->msg;
+ pamc_bp_t binary_prompt = NULL;
- if (!pam_binary_handler_fn
- || pam_binary_handler_fn(pack_in, &pack_out) != PAM_SUCCESS
- || pack_out == NULL) {
+ if (!msgm[count]->msg || !pam_binary_handler_fn) {
goto failed_conversation;
}
- string = (char *) pack_out;
- pack_out = NULL;
- break;
- }
- case PAM_BINARY_MSG:
- {
- const void *pack_in = msgm[count]->msg;
- if (!pam_binary_handler_fn
- || pam_binary_handler_fn(pack_in, NULL) != PAM_SUCCESS) {
+ PAM_BP_RENEW(&binary_prompt,
+ PAM_BP_RCONTROL(msgm[count]->msg),
+ PAM_BP_LENGTH(msgm[count]->msg));
+ PAM_BP_FILL(binary_prompt, 0, PAM_BP_LENGTH(msgm[count]->msg),
+ PAM_BP_RDATA(msgm[count]->msg));
+
+ if (pam_binary_handler_fn(appdata_ptr,
+ &binary_prompt) != PAM_SUCCESS
+ || (binary_prompt == NULL)) {
goto failed_conversation;
}
+ string = (char *) binary_prompt;
+ binary_prompt = NULL;
+
break;
}
default:
@@ -351,11 +315,11 @@ failed_conversation:
free(reply[count].resp);
break;
case PAM_BINARY_PROMPT:
- pam_binary_handler_free((void **) &reply[count].resp);
+ pam_binary_handler_free(appdata_ptr,
+ (pamc_bp_t *) &reply[count].resp);
break;
case PAM_ERROR_MSG:
case PAM_TEXT_INFO:
- case PAM_BINARY_MSG:
/* should not actually be able to get here... */
free(reply[count].resp);
}
diff --git a/contrib/libpam/libpam_misc/xstrdup.c b/contrib/libpam/libpam_misc/xstrdup.c
index e54a87dda7a6..cce476e89f59 100644
--- a/contrib/libpam/libpam_misc/xstrdup.c
+++ b/contrib/libpam/libpam_misc/xstrdup.c
@@ -1,11 +1,4 @@
-/* $Header: /home/morgan/pam/Linux-PAM-0.53/libpam_misc/RCS/xstrdup.c,v 1.4 1996/11/10 20:10:56 morgan Exp $ */
-
-/*
- * $Log: xstrdup.c,v $
- * Revision 1.4 1996/11/10 20:10:56 morgan
- * modification for stack paranoia
- *
- */
+/* $Id: xstrdup.c,v 1.1.1.1 2000/06/20 22:11:25 agmorgan Exp $ */
#include <malloc.h>
#include <string.h>
diff --git a/contrib/libpam/libpamc/License b/contrib/libpam/libpamc/License
new file mode 100644
index 000000000000..9010695470a1
--- /dev/null
+++ b/contrib/libpam/libpamc/License
@@ -0,0 +1,42 @@
+Unless otherwise *explicitly* stated the following text describes the
+licensed conditions under which the contents of this libpamc release
+may be distributed:
+
+-------------------------------------------------------------------------
+Redistribution and use in source and binary forms of libpamc,
+with or without modification, are permitted provided that the
+following conditions are met:
+
+1. Redistributions of source code must retain any existing copyright
+ notice, and this entire permission notice in its entirety,
+ including the disclaimer of warranties.
+
+2. Redistributions in binary form must reproduce all prior and current
+ copyright notices, this list of conditions, and the following
+ disclaimer in the documentation and/or other materials provided
+ with the distribution.
+
+3. The name of any author may not be used to endorse or promote
+ products derived from this software without their specific prior
+ written permission.
+
+ALTERNATIVELY, this product may be distributed under the terms of the
+GNU Library General Public License (LGPL), in which case the
+provisions of the GNU LGPL are required INSTEAD OF the above
+restrictions. (This clause is necessary due to a potential conflict
+between the GNU LGPL 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(S) 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.
+-------------------------------------------------------------------------
+
diff --git a/contrib/libpam/libpamc/Makefile b/contrib/libpam/libpamc/Makefile
new file mode 100644
index 000000000000..1869cfe9dfbc
--- /dev/null
+++ b/contrib/libpam/libpamc/Makefile
@@ -0,0 +1,107 @@
+#
+# $Id: Makefile,v 1.3 2001/02/10 07:17:53 agmorgan Exp $
+#
+
+# lots of debugging information goes to /tmp/pam-debug.log
+#MOREFLAGS += -D"DEBUG"
+
+include ../Make.Rules
+
+ifeq ($(DEBUG_REL),yes)
+ LIBNAME=libpamcd
+else
+ LIBNAME=libpamc
+endif
+VERSION=.$(MAJOR_REL)
+MODIFICATION=.$(MINOR_REL)
+
+CFLAGS += $(MOREFLAGS) $(DYNAMIC) $(STATIC)
+
+# dynamic library names
+
+LIBNAMED = $(LIBNAME).$(DYNTYPE)
+LIBNAMEDNAME = $(LIBNAMED)$(VERSION)
+LIBNAMEDFULL = $(LIBNAMEDNAME)$(MODIFICATION)
+
+# static library name
+
+LIBNAMEDSTATIC = $(LIBNAME).a
+
+LIBOBJECTS = pamc_client.o pamc_converse.o pamc_load.o
+
+ifeq ($(DYNAMIC_LIBPAM),yes)
+DLIBOBJECTS = $(addprefix dynamic/,$(LIBOBJECTS))
+endif
+
+ifeq ($(STATIC_LIBPAM),yes)
+SLIBOBJECTS = $(addprefix static/,$(LIBOBJECTS))
+endif
+
+# ---------------------------------------------
+## rules
+
+all: dirs $(LIBNAMED) $(LIBNAMEDSTATIC)
+
+dirs:
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(MKDIR) dynamic
+endif
+ifeq ($(STATIC_LIBPAM),yes)
+ $(MKDIR) static
+endif
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+static/%.o : %.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+$(LIBNAMED): $(DLIBOBJECTS)
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ ifeq ($(USESONAME),yes)
+ $(LD_L) $(SOSWITCH) $(LIBNAMEDNAME) -o $@ $(DLIBOBJECTS) $(MODULES) $(LINKLIBS)
+ else
+ $(LD_L) -o $@ $(DLIBOBJECTS) $(MODULES)
+ endif
+ ifeq ($(NEEDSONAME),yes)
+ rm -f $(LIBNAMEDFULL)
+ ln -s $(LIBNAMED) $(LIBNAMEDFULL)
+ rm -f $(LIBNAMEDNAME)
+ ln -s $(LIBNAMED) $(LIBNAMEDNAME)
+ endif
+endif
+
+$(LIBNAMEDSTATIC): $(SLIBOBJECTS)
+ifeq ($(STATIC_LIBPAM),yes)
+ $(AR) rc $@ $(SLIBOBJECTS) $(MODULES)
+ $(RANLIB) $@
+endif
+
+install: all
+ $(MKDIR) $(FAKEROOT)$(INCLUDED)
+ $(INSTALL) -m 644 include/security/pam_client.h $(FAKEROOT)$(INCLUDED)
+ifeq ($(DYNAMIC_LIBPAM),yes)
+ $(MKDIR) $(FAKEROOT)$(libdir)
+ $(INSTALL) -m $(SHLIBMODE) $(LIBNAMED) $(FAKEROOT)$(libdir)/$(LIBNAMEDFULL)
+ $(LDCONFIG)
+ ifneq ($(DYNTYPE),"sl")
+ ( cd $(FAKEROOT)$(libdir) ; rm -f $(LIBNAMED) ; ln -s $(LIBNAMEDNAME) $(LIBNAMED) )
+ endif
+endif
+ifeq ($(STATIC_LIBPAM),yes)
+ $(INSTALL) -m 644 $(LIBNAMEDSTATIC) $(FAKEROOT)$(libdir)
+endif
+
+remove:
+ rm -f $(FAKEROOT)$(INCLUDED)/pam_client.h
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMEDFULL)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMED)
+ $(LDCONFIG)
+ rm -f $(FAKEROOT)$(libdir)/$(LIBNAMEDSTATIC)
+
+clean:
+ rm -f a.out core *~ static/*.o dynamic/*.o
+ rm -f *.a *.out *.o *.so ./include/security/*~
+ if [ -d dynamic ]; then rmdir dynamic ; fi
+ if [ -d static ]; then rmdir static ; fi
+
diff --git a/contrib/libpam/libpamc/include/security/pam_client.h b/contrib/libpam/libpamc/include/security/pam_client.h
new file mode 100644
index 000000000000..08aa817a28d6
--- /dev/null
+++ b/contrib/libpam/libpamc/include/security/pam_client.h
@@ -0,0 +1,190 @@
+/*
+ * $Id: pam_client.h,v 1.4 2001/01/20 22:29:47 agmorgan Exp $
+ *
+ * Copyright (c) 1999 Andrew G. Morgan <morgan@linux.kernel.org>
+ *
+ * This header file provides the prototypes for the PAM client API
+ */
+
+#ifndef PAM_CLIENT_H
+#define PAM_CLIENT_H
+
+#include <unistd.h>
+#include <string.h>
+#include <stdio.h>
+
+/* opaque agent handling structure */
+
+typedef struct pamc_handle_s *pamc_handle_t;
+
+/* binary prompt structure pointer */
+#ifndef __u32
+# define __u32 unsigned int
+#endif
+#ifndef __u8
+# define __u8 unsigned char
+#endif
+typedef struct { __u32 length; __u8 control; } *pamc_bp_t;
+
+/*
+ * functions provided by libpamc
+ */
+
+/*
+ * Initialize the agent abstraction library
+ */
+
+pamc_handle_t pamc_start(void);
+
+/*
+ * Terminate the authentication process
+ */
+
+int pamc_end(pamc_handle_t *pch);
+
+/*
+ * force the loading of a specified agent
+ */
+
+int pamc_load(pamc_handle_t pch, const char *agent_id);
+
+/*
+ * Single conversation interface for binary prompts
+ */
+
+int pamc_converse(pamc_handle_t pch, pamc_bp_t *prompt_p);
+
+/*
+ * disable an agent
+ */
+
+int pamc_disable(pamc_handle_t pch, const char *agent_id);
+
+/*
+ * obtain a list of available agents
+ */
+
+char **pamc_list_agents(pamc_handle_t pch);
+
+/*
+ * PAM_BP_ MACROS for creating, destroying and manipulating binary prompts
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+
+#ifndef PAM_BP_ASSERT
+# define PAM_BP_ASSERT(x) do { printf(__FILE__ "(%d): %s\n", \
+ __LINE__, x) ; exit(1); } while (0)
+#endif /* PAM_BP_ASSERT */
+
+#ifndef PAM_BP_CALLOC
+# define PAM_BP_CALLOC calloc
+#endif /* PAM_BP_CALLOC */
+
+#ifndef PAM_BP_FREE
+# define PAM_BP_FREE free
+#endif /* PAM_BP_FREE */
+
+#define __PAM_BP_WOCTET(x,y) (*((y) + (__u8 *)(x)))
+#define __PAM_BP_ROCTET(x,y) (*((y) + (const __u8 *)(x)))
+
+#define PAM_BP_MIN_SIZE (sizeof(__u32) + sizeof(__u8))
+#define PAM_BP_MAX_LENGTH 0x20000 /* an advisory limit */
+#define PAM_BP_WCONTROL(x) (__PAM_BP_WOCTET(x,4))
+#define PAM_BP_RCONTROL(x) (__PAM_BP_ROCTET(x,4))
+#define PAM_BP_SIZE(x) ((__PAM_BP_ROCTET(x,0)<<24)+ \
+ (__PAM_BP_ROCTET(x,1)<<16)+ \
+ (__PAM_BP_ROCTET(x,2)<< 8)+ \
+ (__PAM_BP_ROCTET(x,3) ))
+#define PAM_BP_LENGTH(x) (PAM_BP_SIZE(x) - PAM_BP_MIN_SIZE)
+#define PAM_BP_WDATA(x) (PAM_BP_MIN_SIZE + (__u8 *) (x))
+#define PAM_BP_RDATA(x) (PAM_BP_MIN_SIZE + (const __u8 *) (x))
+
+/* Note, this macro always '\0' terminates renewed packets */
+
+#define PAM_BP_RENEW(old_p, cntrl, data_length) \
+do { \
+ if (old_p) { \
+ if (*(old_p)) { \
+ __u32 __size; \
+ __size = PAM_BP_SIZE(*(old_p)); \
+ memset(*(old_p), 0, __size); \
+ PAM_BP_FREE(*(old_p)); \
+ } \
+ if (cntrl) { \
+ __u32 __size; \
+ \
+ __size = PAM_BP_MIN_SIZE + data_length; \
+ if ((*(old_p) = PAM_BP_CALLOC(1, 1+__size))) { \
+ __PAM_BP_WOCTET(*(old_p), 3) = __size & 0xFF; \
+ __PAM_BP_WOCTET(*(old_p), 2) = (__size>>=8) & 0xFF; \
+ __PAM_BP_WOCTET(*(old_p), 1) = (__size>>=8) & 0xFF; \
+ __PAM_BP_WOCTET(*(old_p), 0) = (__size>>=8) & 0xFF; \
+ (*(old_p))->control = cntrl; \
+ } else { \
+ PAM_BP_ASSERT("out of memory for binary prompt"); \
+ } \
+ } else { \
+ *old_p = NULL; \
+ } \
+ } else { \
+ PAM_BP_ASSERT("programming error, invalid binary prompt pointer"); \
+ } \
+} while (0)
+
+#define PAM_BP_FILL(prmpt, offset, length, data) \
+do { \
+ int bp_length; \
+ __u8 *prompt = (__u8 *) (prmpt); \
+ bp_length = PAM_BP_LENGTH(prompt); \
+ if (bp_length < ((length)+(offset))) { \
+ PAM_BP_ASSERT("attempt to write over end of prompt"); \
+ } \
+ memcpy((offset) + PAM_BP_WDATA(prompt), (data), (length)); \
+} while (0)
+
+#define PAM_BP_EXTRACT(prmpt, offset, length, data) \
+do { \
+ int __bp_length; \
+ const __u8 *__prompt = (const __u8 *) (prmpt); \
+ __bp_length = PAM_BP_LENGTH(__prompt); \
+ if (((offset) < 0) || (__bp_length < ((length)+(offset))) \
+ || ((length) < 0)) { \
+ PAM_BP_ASSERT("invalid extraction from prompt"); \
+ } \
+ memcpy((data), (offset) + PAM_BP_RDATA(__prompt), (length)); \
+} while (0)
+
+
+/* Control types */
+
+#define PAM_BPC_FALSE 0
+#define PAM_BPC_TRUE 1
+
+#define PAM_BPC_OK 0x01 /* continuation packet */
+#define PAM_BPC_SELECT 0x02 /* initialization packet */
+#define PAM_BPC_DONE 0x03 /* termination packet */
+#define PAM_BPC_FAIL 0x04 /* unable to execute */
+
+/* The following control characters are only legal for echanges
+ between an agent and a client (it is the responsibility of the
+ client to enforce this rule in the face of a rogue server): */
+
+#define PAM_BPC_GETENV 0x41 /* obtain client env.var */
+#define PAM_BPC_PUTENV 0x42 /* set client env.var */
+#define PAM_BPC_TEXT 0x43 /* display message */
+#define PAM_BPC_ERROR 0x44 /* display error message */
+#define PAM_BPC_PROMPT 0x45 /* echo'd text prompt */
+#define PAM_BPC_PASS 0x46 /* non-echo'd text prompt*/
+
+/* quick check for prompts that are legal for the client (by
+ implication the server too) to send to libpamc */
+
+#define PAM_BPC_FOR_CLIENT(/* pamc_bp_t */ prompt) \
+ (((prompt)->control <= PAM_BPC_FAIL && (prompt)->control >= PAM_BPC_OK) \
+ ? PAM_BPC_TRUE:PAM_BPC_FALSE)
+
+
+#endif /* PAM_CLIENT_H */
diff --git a/contrib/libpam/libpamc/libpamc.h b/contrib/libpam/libpamc/libpamc.h
new file mode 100644
index 000000000000..1c9397c9071a
--- /dev/null
+++ b/contrib/libpam/libpamc/libpamc.h
@@ -0,0 +1,63 @@
+/*
+ * $Id: libpamc.h,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
+ *
+ * Copyright (c) Andrew G. Morgan <morgan@ftp.kernel.org>
+ *
+ */
+
+#ifndef LIBPAMC_H
+#define LIBPAMC_H
+
+#include <security/pam_client.h>
+#include <security/_pam_macros.h>
+
+#include <sys/stat.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <sys/wait.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <ctype.h>
+
+#define _PAMC_DEFAULT_TOP_FD 10
+
+struct pamc_handle_s {
+ struct pamc_agent_s *current;
+ struct pamc_agent_s *chain;
+ struct pamc_blocked_s *blocked_agents;
+ int max_path;
+ char **agent_paths;
+ int combined_status;
+ int highest_fd_to_close;
+};
+
+typedef struct pamc_blocked_s {
+ char *id; /* <NUL> terminated */
+ struct pamc_blocked_s *next;
+} pamc_blocked_t;
+
+typedef struct pamc_agent_s {
+ char *id;
+ int id_length;
+ struct pamc_agent_s *next;
+ int writer; /* write to agent */
+ int reader; /* read from agent */
+ pid_t pid; /* agent process id */
+} pamc_agent_t;
+
+/* used to build a tree of unique, sorted agent ids */
+
+typedef struct pamc_id_node {
+ struct pamc_id_node *left, *right;
+ int child_count;
+ char *agent_id;
+} pamc_id_node_t;
+
+/* internal function */
+int __pamc_valid_agent_id(int id_length, const char *id);
+
+#define PAMC_SYSTEM_AGENT_PATH "/lib/pamc:/usr/lib/pamc"
+#define PAMC_SYSTEM_AGENT_SEPARATOR ':'
+
+#endif /* LIBPAMC_H */
diff --git a/contrib/libpam/libpamc/pamc_client.c b/contrib/libpam/libpamc/pamc_client.c
new file mode 100644
index 000000000000..19eff429f892
--- /dev/null
+++ b/contrib/libpam/libpamc/pamc_client.c
@@ -0,0 +1,189 @@
+/*
+ * $Id: pamc_client.c,v 1.1.1.1 2000/06/20 22:11:25 agmorgan Exp $
+ *
+ * Copyright (c) Andrew G. Morgan <morgan@ftp.kernel.org>
+ *
+ * pamc_start and pamc_end
+ */
+
+#include "libpamc.h"
+
+/*
+ * liberate path list
+ */
+
+static void __pamc_delete_path_list(pamc_handle_t pch)
+{
+ int i;
+
+ for (i=0; pch->agent_paths[i]; ++i) {
+ free(pch->agent_paths[i]);
+ pch->agent_paths[i] = NULL;
+ }
+
+ free(pch->agent_paths);
+ pch->agent_paths = NULL;
+}
+
+/*
+ * open the pamc library
+ */
+
+pamc_handle_t pamc_start(void)
+{
+ int i, count, last, this;
+ const char *default_path;
+ pamc_handle_t pch;
+
+ pch = calloc(1, sizeof(struct pamc_handle_s));
+ if (pch == NULL) {
+ D(("no memory for *pch"));
+ return NULL;
+ }
+
+ pch->highest_fd_to_close = _PAMC_DEFAULT_TOP_FD;
+
+ default_path = getenv("PAMC_AGENT_PATH");
+ if (default_path == NULL) {
+ default_path = PAMC_SYSTEM_AGENT_PATH;
+ }
+
+ /* number of individual paths */
+ for (count=1, i=0; default_path[i]; ++i) {
+ if (default_path[i] == PAMC_SYSTEM_AGENT_SEPARATOR) {
+ ++count;
+ }
+ }
+
+ pch->agent_paths = calloc(count+1, sizeof(char *));
+ if (pch->agent_paths == NULL) {
+ D(("no memory for path list"));
+ goto drop_pch;
+ }
+
+ this = last = i = 0;
+ while ( default_path[i] || (i != last) ) {
+ if ( default_path[i] == PAMC_SYSTEM_AGENT_SEPARATOR
+ || !default_path[i] ) {
+ int length;
+
+ pch->agent_paths[this] = malloc(length = 1+i-last);
+
+ if (pch->agent_paths[this] == NULL) {
+ D(("no memory for next path"));
+ goto drop_list;
+ }
+
+ memcpy(pch->agent_paths[this], default_path + last, i-last);
+ pch->agent_paths[this][i-last] = '\0';
+ if (length > pch->max_path) {
+ pch->max_path = length;
+ }
+
+ if (++this == count) {
+ break;
+ }
+
+ last = ++i;
+ } else {
+ ++i;
+ }
+ }
+
+ return pch;
+
+drop_list:
+ __pamc_delete_path_list(pch);
+
+drop_pch:
+ free(pch);
+
+ return NULL;
+}
+
+/*
+ * shutdown each of the loaded agents and
+ */
+
+static int __pamc_shutdown_agents(pamc_handle_t pch)
+{
+ int retval = PAM_BPC_TRUE;
+
+ D(("called"));
+
+ while (pch->chain) {
+ pid_t pid;
+ int status;
+ pamc_agent_t *this;
+
+ this = pch->chain;
+ D(("cleaning up agent %p", this));
+ pch->chain = pch->chain->next;
+ this->next = NULL;
+ D(("cleaning up agent: %s", this->id));
+
+ /* close off contact with agent and wait for it to shutdown */
+
+ close(this->writer);
+ this->writer = -1;
+ close(this->reader);
+ this->reader = -1;
+
+ pid = waitpid(this->pid, &status, 0);
+ if (pid == this->pid) {
+
+ D(("is exit:%d, exit val:%d",
+ WIFEXITED(status), WEXITSTATUS(status)));
+
+ if (!(WIFEXITED(status) && (WEXITSTATUS(status) == 0))) {
+ retval = PAM_BPC_FALSE;
+ }
+ } else {
+ D(("problem shutting down agent (%s): pid(%d) != waitpid(%d)!?",
+ this->id, this->pid, pid));
+ retval = PAM_BPC_FALSE;
+ }
+ pid = this->pid = 0;
+
+ memset(this->id, 0, this->id_length);
+ free(this->id);
+ this->id = NULL;
+ this->id_length = 0;
+
+ free(this);
+ this = NULL;
+ }
+
+ return retval;
+}
+
+/*
+ * close the pamc library
+ */
+
+int pamc_end(pamc_handle_t *pch_p)
+{
+ int retval;
+
+ if (pch_p == NULL) {
+ D(("called with no pch_p"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (*pch_p == NULL) {
+ D(("called with no *pch_p"));
+ return PAM_BPC_FALSE;
+ }
+
+ D(("removing path_list"));
+ __pamc_delete_path_list(*pch_p);
+
+ D(("shutting down agents"));
+ retval = __pamc_shutdown_agents(*pch_p);
+
+ D(("freeing *pch_p"));
+ free(*pch_p);
+ *pch_p = NULL;
+
+ return retval;
+}
diff --git a/contrib/libpam/libpamc/pamc_converse.c b/contrib/libpam/libpamc/pamc_converse.c
new file mode 100644
index 000000000000..131789fb15a3
--- /dev/null
+++ b/contrib/libpam/libpamc/pamc_converse.c
@@ -0,0 +1,211 @@
+/*
+ * $Id: pamc_converse.c,v 1.2 2001/01/20 22:29:47 agmorgan Exp $
+ *
+ * Copyright (c) Andrew G. Morgan <morgan@ftp.kernel.org>
+ *
+ * pamc_converse
+ */
+
+#include "libpamc.h"
+
+/*
+ * select agent
+ */
+
+static int __pamc_select_agent(pamc_handle_t pch, char *agent_id)
+{
+ pamc_agent_t *agent;
+
+ for (agent = pch->chain; agent; agent = agent->next) {
+ if (!strcmp(agent->id, agent_id)) {
+ pch->current = agent;
+ return PAM_BPC_TRUE;
+ }
+ }
+
+ D(("failed to locate agent"));
+ pch->current = NULL;
+ return PAM_BPC_FALSE;
+}
+
+/*
+ * pass a binary prompt to the active agent and wait for a reply prompt
+ */
+
+int pamc_converse(pamc_handle_t pch, pamc_bp_t *prompt_p)
+{
+ __u32 size, offset=0;
+ __u8 control, raw[PAM_BP_MIN_SIZE];
+
+ D(("called"));
+
+ if (pch == NULL) {
+ D(("null pch"));
+ goto pamc_converse_failure;
+ }
+
+ if (prompt_p == NULL) {
+ D(("null prompt_p"));
+ goto pamc_converse_failure;
+ }
+
+ if (*prompt_p == NULL) {
+ D(("null *prompt_p"));
+ goto pamc_converse_failure;
+ }
+
+ /* from here on, failures are interoperability problems.. */
+
+ size = PAM_BP_SIZE(*prompt_p);
+ if (size < PAM_BP_MIN_SIZE) {
+ D(("problem with size being too short (%u)", size));
+ goto pamc_unknown_prompt;
+ }
+
+ if (PAM_BPC_FOR_CLIENT(*prompt_p) != PAM_BPC_TRUE) {
+ D(("*prompt_p is not legal for the client to use"));
+ goto pamc_unknown_prompt;
+ }
+
+ /* do we need to select the agent? */
+ if ((*prompt_p)->control == PAM_BPC_SELECT) {
+ char *rawh;
+ int i, retval;
+
+ D(("selecting a specified agent"));
+
+ rawh = (char *) *prompt_p;
+ for (i = PAM_BP_MIN_SIZE; i<size; ++i) {
+ if (rawh[i] == '/') {
+ break;
+ }
+ }
+
+ if ( (i >= size)
+ || !__pamc_valid_agent_id(i-PAM_BP_MIN_SIZE,
+ rawh + PAM_BP_MIN_SIZE) ) {
+ goto pamc_unknown_prompt;
+ }
+
+ rawh[i] = '\0';
+ retval = pamc_load(pch, PAM_BP_MIN_SIZE + rawh);
+ if (retval == PAM_BPC_TRUE) {
+ retval = __pamc_select_agent(pch, PAM_BP_MIN_SIZE + rawh);
+ }
+ rawh[i] = '/';
+
+ if (retval != PAM_BPC_TRUE) {
+ goto pamc_unknown_prompt;
+ }
+
+ D(("agent is loaded"));
+ }
+
+ if (pch->current == NULL) {
+ D(("unable to address agent"));
+ goto pamc_unknown_prompt;
+ }
+
+ /* pump all of the prompt into the agent */
+ do {
+ int rval = write(pch->current->writer,
+ offset + (const __u8 *) (*prompt_p),
+ size - offset);
+ if (rval == -1) {
+ switch (errno) {
+ case EINTR:
+ break;
+ default:
+ D(("problem writing to agent: %s", strerror(errno)));
+ goto pamc_unknown_prompt;
+ }
+ } else {
+ offset += rval;
+ }
+ } while (offset < size);
+
+ D(("whole prompt sent to agent"));
+
+ /* read size and control for response prompt */
+
+ offset = 0;
+ memset(raw, 0, sizeof(raw));
+ do {
+ int rval;
+
+ rval = read(pch->current->reader, raw + offset,
+ PAM_BP_MIN_SIZE - offset);
+
+ if (rval == -1) {
+ switch (errno) {
+ case EINTR:
+ break;
+ default:
+ D(("problem reading from agent: %s", strerror(errno)));
+ goto pamc_unknown_prompt;
+ }
+ } else if (rval) {
+ offset += rval;
+ } else {
+ D(("agent has closed its output pipe - nothing more to read"));
+ goto pamc_converse_failure;
+ }
+ } while (offset < PAM_BP_MIN_SIZE);
+
+ /* construct the whole reply prompt */
+
+ size = PAM_BP_SIZE(raw);
+ control = PAM_BP_RCONTROL(raw);
+ memset(raw, 0, sizeof(raw));
+
+ D(("agent replied with prompt of size %d and control %u",
+ size, control));
+
+ PAM_BP_RENEW(prompt_p, control, size - PAM_BP_MIN_SIZE);
+ if (*prompt_p == NULL) {
+ D(("problem making a new prompt for reply"));
+ goto pamc_unknown_prompt;
+ }
+
+ /* read the rest of the reply prompt -- note offset has the correct
+ value from the previous loop */
+
+ while (offset < size) {
+ int rval = read(pch->current->reader, offset + (__u8 *) *prompt_p,
+ size-offset);
+
+ if (rval == -1) {
+ switch (errno) {
+ case EINTR:
+ break;
+ default:
+ D(("problem reading from agent: %s", strerror(errno)));
+ goto pamc_unknown_prompt;
+ }
+ } else if (rval) {
+ offset += rval;
+ } else {
+ D(("problem reading prompt (%d) with %d to go",
+ size, size-offset));
+ goto pamc_converse_failure;
+ }
+ }
+
+ D(("returning success"));
+
+ return PAM_BPC_TRUE;
+
+pamc_converse_failure:
+
+ D(("conversation failure"));
+ PAM_BP_RENEW(prompt_p, 0, 0);
+ return PAM_BPC_FALSE;
+
+pamc_unknown_prompt:
+
+ /* the server is trying something that the client does not support */
+ D(("unknown prompt"));
+ PAM_BP_RENEW(prompt_p, PAM_BPC_FAIL, 0);
+ return PAM_BPC_TRUE;
+}
+
diff --git a/contrib/libpam/libpamc/pamc_load.c b/contrib/libpam/libpamc/pamc_load.c
new file mode 100644
index 000000000000..01304cc1afe2
--- /dev/null
+++ b/contrib/libpam/libpamc/pamc_load.c
@@ -0,0 +1,477 @@
+/*
+ * $Id: pamc_load.c,v 1.1.1.1 2000/06/20 22:11:26 agmorgan Exp $
+ *
+ * Copyright (c) 1999 Andrew G. Morgan <morgan@ftp.kernel.org>
+ *
+ * pamc_load
+ */
+
+#include "libpamc.h"
+
+static int __pamc_exec_agent(pamc_handle_t pch, pamc_agent_t *agent)
+{
+ char *full_path;
+ int found_agent, length, reset_length, to_agent[2], from_agent[2];
+ int return_code = PAM_BPC_FAIL;
+
+ if (agent->id[agent->id_length] != '\0') {
+ PAM_BP_ASSERT("libpamc: internal error agent_id not terminated");
+ }
+
+ for (length=0; (length < agent->id_length); ++length) {
+ switch (agent->id[length]) {
+ case '/':
+ D(("ill formed agent id"));
+ return PAM_BPC_FAIL;
+ }
+ }
+
+ /* enough memory for any path + this agent */
+ reset_length = 3 + pch->max_path + agent->id_length;
+ D(("reset_length = %d (3+%d+%d)",
+ reset_length, pch->max_path, agent->id_length));
+ full_path = malloc(reset_length);
+ if (full_path == NULL) {
+ D(("no memory for agent path"));
+ return PAM_BPC_FAIL;
+ }
+
+ found_agent = 0;
+ for (length=0; pch->agent_paths[length]; ++length) {
+ struct stat buf;
+
+ D(("path: [%s]", pch->agent_paths[length]));
+ D(("agent id: [%s]", agent->id));
+
+ sprintf(full_path, "%s/%s", pch->agent_paths[length], agent->id);
+
+ D(("looking for agent here: [%s]\n", full_path));
+ if (stat(full_path, &buf) == 0) {
+ D(("file existis"));
+ found_agent = 1;
+ break;
+ }
+ }
+
+ if (! found_agent) {
+ D(("no agent was found"));
+ goto free_and_return;
+ }
+
+ if (pipe(to_agent)) {
+ D(("failed to open pipe to agent"));
+ goto free_and_return;
+ }
+
+ if (pipe(from_agent)) {
+ D(("failed to open pipe from agent"));
+ goto close_the_agent;
+ }
+
+ agent->pid = fork();
+ if (agent->pid == -1) {
+
+ D(("failed to fork for agent"));
+ goto close_both_pipes;
+
+ } else if (agent->pid == 0) {
+
+ int i;
+
+ dup2(from_agent[1], STDOUT_FILENO);
+ dup2(to_agent[0], STDIN_FILENO);
+
+ /* we close all of the files that have filedescriptors lower
+ and equal to twice the highest we have seen, The idea is
+ that we don't want to leak filedescriptors to agents from a
+ privileged client application.
+
+ XXX - this is a heuristic at this point. There is a growing
+ need for an extra 'set param' libpamc function, that could
+ be used to supply info like the highest fd to close etc..
+ */
+
+ if (from_agent[1] > pch->highest_fd_to_close) {
+ pch->highest_fd_to_close = 2*from_agent[1];
+ }
+
+ for (i=0; i <= pch->highest_fd_to_close; ++i) {
+ switch (i) {
+ case STDOUT_FILENO:
+ case STDERR_FILENO:
+ case STDIN_FILENO:
+ /* only these three remain open */
+ break;
+ default:
+ (void) close(i); /* don't care if its not open */
+ }
+ }
+
+ /* we make no attempt to drop other privileges - this library
+ has no idea how that would be done in the general case. It
+ is up to the client application (when calling
+ pamc_converse) to make sure no privilege will leak into an
+ (untrusted) agent. */
+
+ /* we propogate no environment - future versions of this
+ library may have the ability to audit all agent
+ transactions. */
+
+ D(("exec'ing agent %s", full_path));
+ execle(full_path, "pam-agent", NULL, NULL);
+
+ D(("exec failed"));
+ exit(1);
+
+ }
+
+ close(to_agent[0]);
+ close(from_agent[1]);
+
+ agent->writer = to_agent[1];
+ agent->reader = from_agent[0];
+
+ return_code = PAM_BPC_TRUE;
+ goto free_and_return;
+
+close_both_pipes:
+ close(from_agent[0]);
+ close(from_agent[1]);
+
+close_the_agent:
+ close(to_agent[0]);
+ close(to_agent[1]);
+
+free_and_return:
+ memset(full_path, 0, reset_length);
+ free(full_path);
+
+ D(("returning %d", return_code));
+
+ return return_code;
+}
+
+/*
+ * has the named agent been loaded?
+ */
+
+static int __pamc_agent_is_enabled(pamc_handle_t pch, const char *agent_id)
+{
+ pamc_agent_t *agent;
+
+ for (agent = pch->chain; agent; agent = agent->next) {
+ if (!strcmp(agent->id, agent_id)) {
+ D(("agent already loaded"));
+ return PAM_BPC_TRUE;
+ }
+ }
+
+ D(("agent is not loaded"));
+ return PAM_BPC_FALSE;
+}
+
+/*
+ * has the named agent been disabled?
+ */
+
+static int __pamc_agent_is_disabled(pamc_handle_t pch, const char *agent_id)
+{
+ pamc_blocked_t *blocked;
+
+ for (blocked=pch->blocked_agents; blocked; blocked = blocked->next) {
+ if (!strcmp(agent_id, blocked->id)) {
+ D(("agent is disabled"));
+ return PAM_BPC_TRUE;
+ }
+ }
+
+ D(("agent is not disabled"));
+ return PAM_BPC_FALSE;
+}
+
+/*
+ * disable an agent
+ */
+
+int pamc_disable(pamc_handle_t pch, const char *agent_id)
+{
+ pamc_blocked_t *block;
+
+ if (pch == NULL) {
+ D(("pch is NULL"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (agent_id == NULL) {
+ D(("agent_id is NULL"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (__pamc_agent_is_enabled(pch, agent_id) != PAM_BPC_FALSE) {
+ D(("agent is already loaded"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (__pamc_agent_is_disabled(pch, agent_id) != PAM_BPC_FALSE) {
+ D(("agent is already disabled"));
+ return PAM_BPC_TRUE;
+ }
+
+ block = calloc(1, sizeof(pamc_blocked_t));
+ if (block == NULL) {
+ D(("no memory for new blocking structure"));
+ return PAM_BPC_FALSE;
+ }
+
+ block->id = malloc(1 + strlen(agent_id));
+ if (block->id == NULL) {
+ D(("no memory for agent id"));
+ free(block);
+ return PAM_BPC_FALSE;
+ }
+
+ strcpy(block->id, agent_id);
+ block->next = pch->blocked_agents;
+ pch->blocked_agents = block;
+
+ return PAM_BPC_TRUE;
+}
+
+/*
+ * force the loading of a particular agent
+ */
+
+int pamc_load(pamc_handle_t pch, const char *agent_id)
+{
+ pamc_agent_t *agent;
+ int length;
+
+ /* santity checking */
+
+ if (pch == NULL) {
+ D(("pch is NULL"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (agent_id == NULL) {
+ D(("agent_id is NULL"));
+ return PAM_BPC_FALSE;
+ }
+
+ if (__pamc_agent_is_disabled(pch, agent_id) != PAM_BPC_FALSE) {
+ D(("sorry agent is disabled"));
+ return PAM_BPC_FALSE;
+ }
+
+ length = strlen(agent_id);
+
+ /* scan list to see if agent is loaded */
+
+ if (__pamc_agent_is_enabled(pch, agent_id) == PAM_BPC_TRUE) {
+ D(("no need to load an already loaded agent (%s)", agent_id));
+ return PAM_BPC_TRUE;
+ }
+
+ /* not in the list, so we need to load it and add it to the head
+ of the chain */
+
+ agent = calloc(1, sizeof(pamc_agent_t));
+ if (agent == NULL) {
+ D(("no memory for new agent"));
+ return PAM_BPC_FALSE;
+ }
+ agent->id = calloc(1, 1+length);
+ if (agent->id == NULL) {
+ D(("no memory for new agent's id"));
+ goto fail_free_agent;
+ }
+ memcpy(agent->id, agent_id, length);
+ agent->id[length] = '\0';
+ agent->id_length = length;
+
+ if (__pamc_exec_agent(pch, agent) != PAM_BPC_TRUE) {
+ D(("unable to exec agent"));
+ goto fail_free_agent_id;
+ }
+
+ agent->next = pch->chain;
+ pch->chain = agent;
+
+ return PAM_BPC_TRUE;
+
+fail_free_agent_id:
+
+ memset(agent->id, 0, agent->id_length);
+ free(agent->id);
+
+ memset(agent, 0, sizeof(*agent));
+
+fail_free_agent:
+
+ free(agent);
+ return PAM_BPC_FALSE;
+}
+
+/*
+ * what's a valid agent name?
+ */
+
+int __pamc_valid_agent_id(int id_length, const char *id)
+{
+ int post, i;
+
+ for (i=post=0 ; i < id_length; ++i) {
+ int ch = id[i++];
+
+ if (isalpha(ch) || isdigit(ch) || (ch == '_')) {
+ continue;
+ } else if (post && (ch == '.')) {
+ continue;
+ } else if ((i > 1) && (!post) && (ch == '@')) {
+ post = 1;
+ } else {
+ D(("id=%s contains '%c' which is illegal", id, ch));
+ return 0;
+ }
+ }
+
+ if (!i) {
+ D(("length of id is 0"));
+ return 0;
+ } else {
+ return 1; /* id is valid */
+ }
+}
+
+/*
+ * building a tree of available agent names
+ */
+
+static pamc_id_node_t *__pamc_add_node(pamc_id_node_t *root, const char *id,
+ int *counter)
+{
+ if (root) {
+
+ int cmp;
+
+ if ((cmp = strcmp(id, root->agent_id))) {
+ if (cmp > 0) {
+ root->right = __pamc_add_node(root->right, id,
+ &(root->child_count));
+ } else {
+ root->left = __pamc_add_node(root->left, id,
+ &(root->child_count));
+ }
+ }
+
+ return root;
+
+ } else {
+
+ pamc_id_node_t *node = calloc(1, sizeof(pamc_id_node_t));
+
+ if (node) {
+ node->agent_id = malloc(1+strlen(id));
+ if (node->agent_id) {
+ strcpy(node->agent_id, id);
+ } else {
+ free(node);
+ node = NULL;
+ }
+ }
+
+ (*counter)++;
+ return node;
+ }
+}
+
+/*
+ * drop all of the tree and any remaining ids
+ */
+
+static pamc_id_node_t *__pamc_liberate_nodes(pamc_id_node_t *tree)
+{
+ if (tree) {
+ if (tree->agent_id) {
+ free(tree->agent_id);
+ tree->agent_id = NULL;
+ }
+
+ tree->left = __pamc_liberate_nodes(tree->left);
+ tree->right = __pamc_liberate_nodes(tree->right);
+
+ tree->child_count = 0;
+ free(tree);
+ }
+
+ return NULL;
+}
+
+/*
+ * fill a list with the contents of the tree (in ascii order)
+ */
+
+static void __pamc_fill_list_from_tree(pamc_id_node_t *tree, char **agent_list,
+ int *counter)
+{
+ if (tree) {
+ __pamc_fill_list_from_tree(tree->left, agent_list, counter);
+ agent_list[(*counter)++] = tree->agent_id;
+ tree->agent_id = NULL;
+ __pamc_fill_list_from_tree(tree->right, agent_list, counter);
+ }
+}
+
+/*
+ * get a list of the available agents
+ */
+
+char **pamc_list_agents(pamc_handle_t pch)
+{
+ int i, total_agent_count=0;
+ pamc_id_node_t *tree = NULL;
+ char **agent_list;
+
+ /* loop over agent paths */
+
+ for (i=0; pch->agent_paths[i]; ++i) {
+ DIR *dir;
+
+ dir = opendir(pch->agent_paths[i]);
+ if (dir) {
+ struct dirent *item;
+
+ while ((item = readdir(dir))) {
+
+ /* this is a cheat on recognizing agent_ids */
+ if (!__pamc_valid_agent_id(strlen(item->d_name),
+ item->d_name)) {
+ continue;
+ }
+
+ tree = __pamc_add_node(tree, item->d_name, &total_agent_count);
+ }
+
+ closedir(dir);
+ }
+ }
+
+ /* now, we build a list of ids */
+ D(("total of %d available agents\n", total_agent_count));
+
+ agent_list = calloc(total_agent_count+1, sizeof(char *));
+ if (agent_list) {
+ int counter=0;
+
+ __pamc_fill_list_from_tree(tree, agent_list, &counter);
+ if (counter != total_agent_count) {
+ PAM_BP_ASSERT("libpamc: internal error transcribing tree");
+ }
+ } else {
+ D(("no memory for agent list"));
+ }
+
+ __pamc_liberate_nodes(tree);
+
+ return agent_list;
+}
diff --git a/contrib/libpam/libpamc/test/agents/secret@here b/contrib/libpam/libpamc/test/agents/secret@here
new file mode 100755
index 000000000000..afdcbaa801aa
--- /dev/null
+++ b/contrib/libpam/libpamc/test/agents/secret@here
@@ -0,0 +1,308 @@
+#!/usr/bin/perl
+#
+# This is a simple example PAM authentication agent, it implements a
+# simple shared secret authentication scheme. The PAM module pam_secret.so
+# is its counter part. Both the agent and the remote server are able to
+# authenticate one another, but the server is given the opportunity to
+# ignore a failed authentication.
+#
+
+$^W = 1;
+use strict;
+use IPC::Open2;
+$| = 1;
+
+# display extra information to STDERR
+my $debug = 0;
+if (scalar @ARGV) {
+ $debug = 1;
+}
+
+# Globals
+
+my %state;
+my $default_key;
+
+my $next_key = $$;
+
+# loop over binary prompts
+for (;;) {
+ my ($control, $data) = ReadBinaryPrompt();
+ my ($reply_control, $reply_data);
+
+ if ($control == 0) {
+ if ($debug) {
+ print STDERR "agent: no packet to read\n";
+ }
+ last;
+ } elsif ($control == 0x02) {
+ ($reply_control, $reply_data) = HandleAgentSelection($data);
+ } elsif ($control == 0x01) {
+ ($reply_control, $reply_data) = HandleContinuation($data);
+ } else {
+ if ($debug) {
+ print STDERR
+ "agent: unrecognized packet $control {$data} to read\n";
+ }
+ ($reply_control, $reply_data) = (0x04, "");
+ }
+
+ WriteBinaryPrompt($reply_control, $reply_data);
+}
+
+# Only willing to exit well if we've completed our authentication exchange
+
+if (scalar keys %state) {
+ if ($debug) {
+ print STDERR "The following sessions are still active:\n ";
+ print STDERR join ', ', keys %state;
+ print STDERR "\n";
+ }
+ exit 1;
+} else {
+ exit 0;
+}
+
+sub HandleAgentSelection ($) {
+ my ($data) = @_;
+
+ unless ( $data =~ /^([a-zA-Z0-9_]+\@?[a-zA-Z0-9_.]*)\/(.*)$/ ) {
+ return (0x04, "");
+ }
+
+ my ($agent_name, $payload) = ($1, $2);
+ if ($debug) {
+ print STDERR "agent: ". "agent=$agent_name, payload=$payload\n";
+ }
+
+ # this agent has a defined name
+ if ($agent_name ne "secret\@here") {
+ if ($debug) {
+ print STDERR "bad agent name: [$agent_name]\n";
+ }
+ return (0x04, "");
+ }
+
+ # the selection request is acompanied with a hexadecimal cookie
+ my @tokens = split '\|', $payload;
+
+ unless ((scalar @tokens) == 2) {
+ if ($debug) {
+ print STDERR "bad payload\n";
+ }
+ return (0x04, "");
+ }
+
+ unless ($tokens[1] =~ /^[a-z0-9]+$/) {
+ if ($debug) {
+ print STDERR "bad server cookie\n";
+ }
+ return (0x04, "");
+ }
+
+ my $shared_secret = IdentifyLocalSecret($tokens[0]);
+
+ unless (defined $shared_secret) {
+ # make a secret up
+ if ($debug) {
+ print STDERR "agent: cannot authenticate user\n";
+ }
+ $shared_secret = GetRandom();
+ }
+
+ my $local_cookie = GetRandom();
+ $default_key = $next_key++;
+
+ $state{$default_key} = $local_cookie ."|". $tokens[1] ."|". $shared_secret;
+
+ if ($debug) {
+ print STDERR "agent: \$state{$default_key} = $state{$default_key}\n";
+ }
+
+ return (0x01, $default_key ."|". $local_cookie);
+}
+
+sub HandleContinuation ($) {
+ my ($data) = @_;
+
+ my ($key, $server_digest) = split '\|', $data;
+
+ unless (defined $state{$key}) {
+ # retries and out of sequence prompts are not permitted
+ return (0x04, "");
+ }
+
+ my $expected_digest = CreateDigest($state{$key});
+ my ($local_cookie, $remote_cookie, $shared_secret)
+ = split '\|', $state{$key};
+ delete $state{$key};
+
+ unless ($expected_digest eq $server_digest) {
+ if ($debug) {
+ print STDERR "agent: don't trust server - faking reply\n";
+ print STDERR "agent: got ($server_digest)\n";
+ print STDERR "agent: expected ($expected_digest)\n";
+ }
+
+ ## FIXME: Agent should exchange a prompt with the client warning
+ ## that the server is faking us out.
+
+ return (0x03, CreateDigest($expected_digest . $data . GetRandom()));
+ }
+
+ if ($debug) {
+ print STDERR "agent: server appears to know the secret\n";
+ }
+
+ my $session_authenticated_ticket =
+ CreateDigest($remote_cookie."|".$shared_secret."|".$local_cookie);
+
+ # FIXME: Agent should set a derived session key environment
+ # variable (available for the client (and its children) to sign
+ # future data exchanges.
+
+ if ($debug) {
+ print STDERR "agent: should putenv("
+ ."\"AUTH_SESSION_TICKET=$session_authenticated_ticket\")\n";
+ }
+
+ # return agent's authenticating digest
+ return (0x03, CreateDigest($shared_secret."|".$remote_cookie
+ ."|".$local_cookie));
+}
+
+sub ReadBinaryPrompt {
+ my $buffer = " ";
+ my $count = read(STDIN, $buffer, 5);
+ if ($count == 0) {
+ # no more packets to read
+ return (0, "");
+ }
+
+ if ($count != 5) {
+ # broken packet header
+ return (-1, "");
+ }
+
+ my ($length, $control) = unpack("N C", $buffer);
+ if ($length < 5) {
+ # broken packet length
+ return (-1, "");
+ }
+
+ my $data = "";
+ $length -= 5;
+ while ($count = read(STDIN, $buffer, $length)) {
+ $data .= $buffer;
+ if ($count != $length) {
+ $length -= $count;
+ next;
+ }
+
+ if ($debug) {
+ print STDERR "agent: ". "data is [$data]\n";
+ }
+
+ return ($control, $data);
+ }
+
+ # broken packet data
+ return (-1, "");
+}
+
+sub WriteBinaryPrompt ($$) {
+ my ($control, $data) = @_;
+
+ my $length = 5 + length($data);
+ if ($debug) {
+ printf STDERR "agent: ". "{%d|0x%.2x|%s}\n", $length, $control, $data;
+ }
+ my $bp = pack("N C a*", $length, $control, $data);
+ print STDOUT $bp;
+ if ($debug) {
+ printf STDERR "agent: ". "agent has replied\n";
+ }
+}
+
+##
+## Here is where we parse the simple secret file
+## The format of this file is a list of lines of the following form:
+##
+## user@client0.host.name secret_string1
+## user@client1.host.name secret_string2
+## user@client2.host.name secret_string3
+##
+
+sub IdentifyLocalSecret ($) {
+ my ($identifier) = @_;
+ my $secret;
+
+ if (open SECRETS, "< ". (getpwuid($<))[7] ."/.secret\@here") {
+ my $line;
+ while (defined ($line = <SECRETS>)) {
+ my ($id, $sec) = split /[\s]+/, $line;
+ if ((defined $id) && ($id eq $identifier)) {
+ $secret = $sec;
+ last;
+ }
+ }
+ close SECRETS;
+ }
+
+ return $secret;
+}
+
+## Here is where we generate a message digest
+
+sub CreateDigest ($) {
+ my ($data) = @_;
+
+ my $pid = open2(\*MD5out, \*MD5in, "/usr/bin/md5sum -")
+ or die "you'll need /usr/bin/md5sum installed";
+
+ my $oldfd = select MD5in; $|=1; select $oldfd;
+ if ($debug) {
+ print STDERR "agent: ". "telling md5: <$data>\n";
+ }
+ print MD5in "$data";
+ close MD5in;
+ my $reply = <MD5out>;
+ ($reply) = split /\s/, $reply;
+ if ($debug) {
+ print STDERR "agent: ". "md5 said: <$reply>\n";
+ }
+ close MD5out;
+
+ return $reply;
+}
+
+## get a random number
+
+sub GetRandom {
+
+ if ( -r "/dev/urandom" ) {
+ open RANDOM, "< /dev/urandom" or die "crazy";
+
+ my $i;
+ my $reply = "";
+
+ for ($i=0; $i<4; ++$i) {
+ my $buffer = " ";
+ while (read(RANDOM, $buffer, 4) != 4) {
+ ;
+ }
+ $reply .= sprintf "%.8x", unpack("N", $buffer);
+ if ($debug) {
+ print STDERR "growing reply: [$reply]\n";
+ }
+ }
+ close RANDOM;
+
+ return $reply;
+ } else {
+ print STDERR "agent: ". "[got linux?]\n";
+ return "%.8x%.8x%.8x%.8x", time, time, time, time;
+ }
+
+}
+
diff --git a/contrib/libpam/libpamc/test/modules/Makefile b/contrib/libpam/libpamc/test/modules/Makefile
new file mode 100644
index 000000000000..480654629764
--- /dev/null
+++ b/contrib/libpam/libpamc/test/modules/Makefile
@@ -0,0 +1,9 @@
+CFLAGS = -g -fPIC -I"../../include"
+
+pam_secret.so: pam_secret.o
+ ld -x --shared -o pam_secret.so pam_secret.o -lc
+
+.o.c:
+
+clean:
+ rm -f *.so *.o
diff --git a/contrib/libpam/libpamc/test/modules/pam_secret.c b/contrib/libpam/libpamc/test/modules/pam_secret.c
new file mode 100644
index 000000000000..f59e53a54727
--- /dev/null
+++ b/contrib/libpam/libpamc/test/modules/pam_secret.c
@@ -0,0 +1,670 @@
+/*
+ * $Id: pam_secret.c,v 1.2 2001/01/20 22:29:47 agmorgan Exp $
+ *
+ * Copyright (c) 1999 Andrew G. Morgan <morgan@linux.kernel.org>
+ */
+
+/*
+ * WARNING: AS WRITTEN THIS CODE IS NOT SECURE. THE MD5 IMPLEMENTATION
+ * NEEDS TO BE INTEGRATED MORE NATIVELY.
+ */
+
+/* #define DEBUG */
+
+#include <fcntl.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#include <security/pam_modules.h>
+#include <security/pam_client.h>
+#include <security/_pam_macros.h>
+
+/*
+ * This is a sample module that demonstrates the use of binary prompts
+ * and how they can be used to implement sophisticated authentication
+ * schemes.
+ */
+
+struct ps_state_s {
+ int retval; /* last retval returned by the authentication fn */
+ int state; /* what state the module was in when it
+ returned incomplete */
+
+ char *username; /* the name of the local user */
+
+ char server_cookie[33]; /* storage for 32 bytes of server cookie */
+ char client_cookie[33]; /* storage for 32 bytes of client cookie */
+
+ char *secret_data; /* pointer to <NUL> terminated secret_data */
+ int invalid_secret; /* indication of whether the secret is valid */
+
+ pamc_bp_t current_prompt; /* place to store the current prompt */
+ pamc_bp_t current_reply; /* place to receive the reply prompt */
+};
+
+#define PS_STATE_ID "PAM_SECRET__STATE"
+#define PS_AGENT_ID "secret@here"
+#define PS_STATE_DEAD 0
+#define PS_STATE_INIT 1
+#define PS_STATE_PROMPT1 2
+#define PS_STATE_PROMPT2 3
+
+#define MAX_LEN_HOSTNAME 512
+#define MAX_FILE_LINE_LEN 1024
+
+/*
+ * Routine for generating 16*8 bits of random data represented in ASCII hex
+ */
+
+static int generate_cookie(unsigned char *buffer_33)
+{
+ static const char hexarray[] = "0123456789abcdef";
+ int i, fd;
+
+ /* fill buffer_33 with 32 hex characters (lower case) + '\0' */
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd < 0) {
+ D(("failed to open /dev/urandom"));
+ return 0;
+ }
+ read(fd, buffer_33 + 16, 16);
+ close(fd);
+
+ /* expand top 16 bytes into 32 nibbles */
+ for (i=0; i<16; ++i) {
+ buffer_33[2*i ] = hexarray[(buffer_33[16+i] & 0xf0)>>4];
+ buffer_33[2*i+1] = hexarray[(buffer_33[16+i] & 0x0f)];
+ }
+
+ buffer_33[32] = '\0';
+
+ return 1;
+}
+
+/*
+ * XXX - This is a hack, and is fundamentally insecure. Its subject to
+ * all sorts of attacks not to mention the fact that all our secrets
+ * will be displayed on the command line for someone doing 'ps' to
+ * see. This is just for programming convenience in this instance, it
+ * needs to be replaced with the md5 code. Although I am loath to
+ * add yet another instance of md5 code to the Linux-PAM source code.
+ * [Need to think of a cleaner way to do this for the distribution as
+ * a whole...]
+ */
+
+#define COMMAND_FORMAT "/bin/echo -n '%s|%s|%s'|/usr/bin/md5sum -"
+
+int create_digest(const char *d1, const char *d2, const char *d3,
+ char *buffer_33)
+{
+ int length;
+ char *buffer;
+ FILE *pipe;
+
+ length = strlen(d1)+strlen(d2)+strlen(d3)+sizeof(COMMAND_FORMAT);
+ buffer = malloc(length);
+ if (buffer == NULL) {
+ D(("out of memory"));
+ return 0;
+ }
+
+ sprintf(buffer, COMMAND_FORMAT, d1,d2,d3);
+
+ D(("executing pipe [%s]", buffer));
+ pipe = popen(buffer, "r");
+ memset(buffer, 0, length);
+ free(buffer);
+
+ if (pipe == NULL) {
+ D(("failed to launch pipe"));
+ return 0;
+ }
+
+ if (fgets(buffer_33, 33, pipe) == NULL) {
+ D(("failed to read digest"));
+ return 0;
+ }
+
+ if (strlen(buffer_33) != 32) {
+ D(("digest was not 32 chars"));
+ return 0;
+ }
+
+ fclose(pipe);
+
+ D(("done [%s]", buffer_33));
+
+ return 1;
+}
+
+/*
+ * method to attempt to instruct the application's conversation function
+ */
+
+static int converse(pam_handle_t *pamh, struct ps_state_s *new)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("called"));
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS) {
+ struct pam_message msg;
+ struct pam_response *single_reply;
+ const struct pam_message *msg_ptr;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_style = PAM_BINARY_PROMPT;
+ msg.msg = (const char *) new->current_prompt;
+ msg_ptr = &msg;
+
+ single_reply = NULL;
+ retval = conv->conv(1, &msg_ptr, &single_reply, conv->appdata_ptr);
+ if (retval == PAM_SUCCESS) {
+ if ((single_reply == NULL) || (single_reply->resp == NULL)) {
+ retval == PAM_CONV_ERR;
+ } else {
+ new->current_reply = (pamc_bp_t) single_reply->resp;
+ single_reply->resp = NULL;
+ }
+ }
+
+ if (single_reply) {
+ free(single_reply);
+ }
+ }
+
+#ifdef DEBUG
+ if (retval == PAM_SUCCESS) {
+ D(("reply has length=%d and control=%u",
+ PAM_BP_LENGTH(new->current_reply),
+ PAM_BP_CONTROL(new->current_reply)));
+ }
+ D(("returning %s", pam_strerror(pamh, retval)));
+#endif
+
+ return retval;
+}
+
+/*
+ * identify the secret in question
+ */
+
+#define SECRET_FILE_FORMAT "%s/.secret@here"
+
+char *identify_secret(char *identity, const char *user)
+{
+ struct passwd *pwd;
+ char *temp;
+ FILE *secrets;
+ int length_id;
+
+ pwd = getpwnam(user);
+ if ((pwd == NULL) || (pwd->pw_dir == NULL)) {
+ D(("user [%s] is not known", user));
+ }
+
+ length_id = strlen(pwd->pw_dir) + sizeof(SECRET_FILE_FORMAT);
+ temp = malloc(length_id);
+ if (temp == NULL) {
+ D(("out of memory"));
+ pwd = NULL;
+ return NULL;
+ }
+
+ sprintf(temp, SECRET_FILE_FORMAT, pwd->pw_dir);
+ pwd = NULL;
+
+ D(("opening key file [%s]", temp));
+ secrets = fopen(temp, "r");
+ memset(temp, 0, length_id);
+
+ if (secrets == NULL) {
+ D(("failed to open key file"));
+ return NULL;
+ }
+
+ length_id = strlen(identity);
+ temp = malloc(MAX_FILE_LINE_LEN);
+
+ for (;;) {
+ char *secret = NULL;
+
+ if (fgets(temp, MAX_FILE_LINE_LEN, secrets) == NULL) {
+ fclose(secrets);
+ return NULL;
+ }
+
+ D(("cf[%s][%s]", identity, temp));
+ if (memcmp(temp, identity, length_id)) {
+ continue;
+ }
+
+ D(("found entry"));
+ fclose(secrets);
+
+ for (secret=temp+length_id; *secret; ++secret) {
+ if (!(*secret == ' ' || *secret == '\n' || *secret == '\t')) {
+ break;
+ }
+ }
+
+ memmove(temp, secret, MAX_FILE_LINE_LEN-(secret-(temp+length_id)));
+ secret = temp;
+
+ for (; *secret; ++secret) {
+ if (*secret == ' ' || *secret == '\n' || *secret == '\t') {
+ break;
+ }
+ }
+
+ if (*secret) {
+ *secret = '\0';
+ }
+
+ D(("secret found [%s]", temp));
+
+ return temp;
+ }
+
+ /* NOT REACHED */
+}
+
+/*
+ * function to perform the two message authentication process
+ * (with support for event driven conversation functions)
+ */
+
+static int auth_sequence(pam_handle_t *pamh,
+ const struct ps_state_s *old, struct ps_state_s *new)
+{
+ const char *rhostname;
+ const char *rusername;
+ int retval;
+
+ retval = pam_get_item(pamh, PAM_RUSER, (const void **) &rusername);
+ if ((retval != PAM_SUCCESS) || (rusername == NULL)) {
+ D(("failed to obtain an rusername"));
+ new->state = PS_STATE_DEAD;
+ return PAM_AUTH_ERR;
+ }
+
+ retval = pam_get_item(pamh, PAM_RHOST, (const void **) &rhostname);
+ if ((retval != PAM_SUCCESS) || (rhostname == NULL)) {
+ D(("failed to identify local hostname: ", pam_strerror(pamh, retval)));
+ new->state = PS_STATE_DEAD;
+ return PAM_AUTH_ERR;
+ }
+
+ D(("switch on new->state=%d [%s@%s]", new->state, rusername, rhostname));
+ switch (new->state) {
+
+ case PS_STATE_INIT:
+ {
+ const char *user = NULL;
+
+ retval = pam_get_user(pamh, &user, NULL);
+
+ if ((retval == PAM_SUCCESS) && (user == NULL)) {
+ D(("success but no username?"));
+ new->state = PS_STATE_DEAD;
+ retval = PAM_USER_UNKNOWN;
+ }
+
+ if (retval != PAM_SUCCESS) {
+ if (retval == PAM_CONV_AGAIN) {
+ retval = PAM_INCOMPLETE;
+ } else {
+ new->state = PS_STATE_DEAD;
+ }
+ D(("state init failed: %s", pam_strerror(pamh, retval)));
+ return retval;
+ }
+
+ /* nothing else in this 'case' can be retried */
+
+ new->username = strdup(user);
+ if (new->username == NULL) {
+ D(("out of memory"));
+ new->state = PS_STATE_DEAD;
+ return PAM_BUF_ERR;
+ }
+
+ if (! generate_cookie(new->server_cookie)) {
+ D(("problem generating server cookie"));
+ new->state = PS_STATE_DEAD;
+ return PAM_ABORT;
+ }
+
+ new->current_prompt = NULL;
+ PAM_BP_RENEW(&new->current_prompt, PAM_BPC_SELECT,
+ sizeof(PS_AGENT_ID) + strlen(rusername) + 1
+ + strlen(rhostname) + 1 + 32);
+ sprintf(PAM_BP_WDATA(new->current_prompt),
+ PS_AGENT_ID "/%s@%s|%.32s", rusername, rhostname,
+ new->server_cookie);
+
+ /* note, the BP is guaranteed by the spec to be <NUL> terminated */
+ D(("initialization packet [%s]", PAM_BP_DATA(new->current_prompt)));
+
+ /* fall through */
+ new->state = PS_STATE_PROMPT1;
+
+ D(("fall through to state_prompt1"));
+ }
+
+ case PS_STATE_PROMPT1:
+ {
+ int i, length;
+
+ /* send {secret@here/jdoe@client.host|<s_cookie>} */
+ retval = converse(pamh, new);
+ if (retval != PAM_SUCCESS) {
+ if (retval == PAM_CONV_AGAIN) {
+ D(("conversation failed to complete"));
+ return PAM_INCOMPLETE;
+ } else {
+ new->state = PS_STATE_DEAD;
+ return retval;
+ }
+ }
+
+ if (retval != PAM_SUCCESS) {
+ D(("failed to read ruser@rhost"));
+ new->state = PS_STATE_DEAD;
+ return PAM_AUTH_ERR;
+ }
+
+ /* expect to receive the following {<seqid>|<a_cookie>} */
+ if (new->current_reply == NULL) {
+ D(("converstation returned [%s] but gave no reply",
+ pam_strerror(pamh, retval)));
+ new->state = PS_STATE_DEAD;
+ return PAM_CONV_ERR;
+ }
+
+ /* find | */
+ length = PAM_BP_LENGTH(new->current_reply);
+ for (i=0; i<length; ++i) {
+ if (PAM_BP_RDATA(new->current_reply)[i] == '|') {
+ break;
+ }
+ }
+ if (i >= length) {
+ D(("malformed response (no |) of length %d", length));
+ new->state = PS_STATE_DEAD;
+ return PAM_CONV_ERR;
+ }
+ if ((length - ++i) != 32) {
+ D(("cookie is incorrect length (%d,%d) %d != 32",
+ length, i, length-i));
+ new->state = PS_STATE_DEAD;
+ return PAM_CONV_ERR;
+ }
+
+ /* copy client cookie */
+ memcpy(new->client_cookie, PAM_BP_RDATA(new->current_reply)+i, 32);
+
+ /* generate a prompt that is length(seqid) + length(|) + 32 long */
+ PAM_BP_RENEW(&new->current_prompt, PAM_BPC_OK, i+32);
+ /* copy the head of the response prompt */
+ memcpy(PAM_BP_WDATA(new->current_prompt),
+ PAM_BP_RDATA(new->current_reply), i);
+ PAM_BP_RENEW(&new->current_reply, 0, 0);
+
+ /* look up the secret */
+ new->invalid_secret = 0;
+
+ if (new->secret_data == NULL) {
+ char *ruser_rhost;
+
+ ruser_rhost = malloc(strlen(rusername)+2+strlen(rhostname));
+ if (ruser_rhost == NULL) {
+ D(("out of memory"));
+ new->state = PS_STATE_DEAD;
+ return PAM_BUF_ERR;
+ }
+ sprintf(ruser_rhost, "%s@%s", rusername, rhostname);
+ new->secret_data = identify_secret(ruser_rhost, new->username);
+
+ memset(ruser_rhost, 0, strlen(ruser_rhost));
+ free(ruser_rhost);
+ }
+
+ if (new->secret_data == NULL) {
+ D(("secret not found for user"));
+ new->invalid_secret = 1;
+
+ /* need to make up a secret */
+ new->secret_data = malloc(32 + 1);
+ if (new->secret_data == NULL) {
+ D(("out of memory"));
+ new->state = PS_STATE_DEAD;
+ return PAM_BUF_ERR;
+ }
+ if (! generate_cookie(new->secret_data)) {
+ D(("what's up - no fake cookie generated?"));
+ new->state = PS_STATE_DEAD;
+ return PAM_ABORT;
+ }
+ }
+
+ /* construct md5[<client_cookie>|<server_cookie>|<secret_data>] */
+ if (! create_digest(new->client_cookie, new->server_cookie,
+ new->secret_data,
+ PAM_BP_WDATA(new->current_prompt)+i)) {
+ D(("md5 digesting failed"));
+ new->state = PS_STATE_DEAD;
+ return PAM_ABORT;
+ }
+
+ /* prompt2 is now constructed - fall through to send it */
+ }
+
+ case PS_STATE_PROMPT2:
+ {
+ /* send {<seqid>|md5[<client_cookie>|<server_cookie>|<secret_data>]} */
+ retval = converse(pamh, new);
+ if (retval != PAM_SUCCESS) {
+ if (retval == PAM_CONV_AGAIN) {
+ D(("conversation failed to complete"));
+ return PAM_INCOMPLETE;
+ } else {
+ new->state = PS_STATE_DEAD;
+ return retval;
+ }
+ }
+
+ /* After we complete this section, we should not be able to
+ recall this authentication function. So, we force all
+ future calls into the weeds. */
+
+ new->state = PS_STATE_DEAD;
+
+ /* expect reply:{md5[<secret_data>|<server_cookie>|<client_cookie>]} */
+
+ {
+ int cf;
+ char expectation[33];
+
+ if (!create_digest(new->secret_data, new->server_cookie,
+ new->client_cookie, expectation)) {
+ new->state = PS_STATE_DEAD;
+ return PAM_ABORT;
+ }
+
+ cf = strcmp(expectation, PAM_BP_RDATA(new->current_reply));
+ memset(expectation, 0, sizeof(expectation));
+ if (cf || new->invalid_secret) {
+ D(("failed to authenticate"));
+ return PAM_AUTH_ERR;
+ }
+ }
+
+ D(("correctly authenticated :)"));
+ return PAM_SUCCESS;
+ }
+
+ default:
+ new->state = PS_STATE_DEAD;
+
+ case PS_STATE_DEAD:
+
+ D(("state is currently dead/unknown"));
+ return PAM_AUTH_ERR;
+ }
+
+ fprintf(stderr, "pam_secret: this should not be reached\n");
+ return PAM_ABORT;
+}
+
+static void clean_data(pam_handle_t *pamh, void *datum, int error_status)
+{
+ struct ps_state_s *data = datum;
+
+ D(("liberating datum=%p", datum));
+
+ if (data) {
+ D(("renew prompt"));
+ PAM_BP_RENEW(&data->current_prompt, 0, 0);
+ D(("renew reply"));
+ PAM_BP_RENEW(&data->current_reply, 0, 0);
+ D(("overwrite datum"));
+ memset(data, 0, sizeof(struct ps_state_s));
+ D(("liberate datum"));
+ free(data);
+ }
+
+ D(("done."));
+}
+
+/*
+ * front end for the authentication function
+ */
+
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval;
+ struct ps_state_s *new_data;
+ const struct ps_state_s *old_data;
+
+ D(("called"));
+
+ new_data = calloc(1, sizeof(struct ps_state_s));
+ if (new_data == NULL) {
+ D(("out of memory"));
+ return PAM_BUF_ERR;
+ }
+ new_data->retval = PAM_SUCCESS;
+
+ retval = pam_get_data(pamh, PS_STATE_ID, (const void **) &old_data);
+ if (retval == PAM_SUCCESS) {
+ new_data->state = old_data->state;
+ memcpy(new_data->server_cookie, old_data->server_cookie, 32);
+ memcpy(new_data->client_cookie, old_data->client_cookie, 32);
+ if (old_data->username) {
+ new_data->username = strdup(old_data->username);
+ }
+ if (old_data->secret_data) {
+ new_data->secret_data = strdup(old_data->secret_data);
+ }
+ if (old_data->current_prompt) {
+ int length;
+
+ length = PAM_BP_LENGTH(old_data->current_prompt);
+ PAM_BP_RENEW(&new_data->current_prompt,
+ PAM_BP_CONTROL(old_data->current_prompt), length);
+ PAM_BP_FILL(new_data->current_prompt, 0, length,
+ PAM_BP_RDATA(old_data->current_prompt));
+ }
+ /* don't need to duplicate current_reply */
+ } else {
+ old_data = NULL;
+ new_data->state = PS_STATE_INIT;
+ }
+
+ D(("call auth_sequence"));
+ new_data->retval = auth_sequence(pamh, old_data, new_data);
+ D(("returned from auth_sequence"));
+
+ retval = pam_set_data(pamh, PS_STATE_ID, new_data, clean_data);
+ if (retval != PAM_SUCCESS) {
+ D(("unable to store new_data"));
+ } else {
+ retval = new_data->retval;
+ }
+
+ old_data = new_data = NULL;
+
+ D(("done (%d)", retval));
+ return retval;
+}
+
+/*
+ * front end for the credential setting function
+ */
+
+#define AUTH_SESSION_TICKET_ENV_FORMAT "AUTH_SESSION_TICKET="
+
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ int retval;
+ const struct ps_state_s *old_data;
+
+ D(("called"));
+
+ /* XXX - need to pay attention to the various flavors of call */
+
+ /* XXX - need provide an option to turn this feature on/off: if
+ other modules want to supply an AUTH_SESSION_TICKET, we should
+ leave it up to the admin which module dominiates. */
+
+ retval = pam_get_data(pamh, PS_STATE_ID, (const void **) &old_data);
+ if (retval != PAM_SUCCESS) {
+ D(("no data to base decision on"));
+ return PAM_AUTH_ERR;
+ }
+
+ /*
+ * If ok, export a derived shared secret session ticket to the
+ * client's PAM environment - the ticket has the form
+ *
+ * AUTH_SESSION_TICKET =
+ * md5[<server_cookie>|<secret_data>|<client_cookie>]
+ *
+ * This is a precursor to supporting a spoof resistant trusted
+ * path mechanism. This shared secret ticket can be used to add
+ * a hard-to-guess checksum to further authentication data.
+ */
+
+ retval = old_data->retval;
+ if (retval == PAM_SUCCESS) {
+ char envticket[sizeof(AUTH_SESSION_TICKET_ENV_FORMAT)+32];
+
+ memcpy(envticket, AUTH_SESSION_TICKET_ENV_FORMAT,
+ sizeof(AUTH_SESSION_TICKET_ENV_FORMAT));
+
+ if (! create_digest(old_data->server_cookie, old_data->secret_data,
+ old_data->client_cookie,
+ envticket+sizeof(AUTH_SESSION_TICKET_ENV_FORMAT)-1
+ )) {
+ D(("unable to generate a digest for session ticket"));
+ return PAM_ABORT;
+ }
+
+ D(("putenv[%s]", envticket));
+ retval = pam_putenv(pamh, envticket);
+ memset(envticket, 0, sizeof(envticket));
+ }
+
+ old_data = NULL;
+ D(("done (%d)", retval));
+
+ return retval;
+}
diff --git a/contrib/libpam/libpamc/test/regress/Makefile b/contrib/libpam/libpamc/test/regress/Makefile
new file mode 100644
index 000000000000..ff63e5f087ad
--- /dev/null
+++ b/contrib/libpam/libpamc/test/regress/Makefile
@@ -0,0 +1,7 @@
+CFLAGS = -g -I ../../include
+
+test.libpamc: test.libpamc.o
+ $(CC) -o $@ $< -L ../.. -lpamc
+
+clean:
+ rm -f test.libpamc test.libpamc.o
diff --git a/contrib/libpam/libpamc/test/regress/run_test.sh b/contrib/libpam/libpamc/test/regress/run_test.sh
new file mode 100755
index 000000000000..a1bf010b11c1
--- /dev/null
+++ b/contrib/libpam/libpamc/test/regress/run_test.sh
@@ -0,0 +1,6 @@
+#!/bin/bash
+
+export LD_LIBRARY_PATH=../..
+export PAMC_AGENT_PATH="../agents"
+
+./test.libpamc
diff --git a/contrib/libpam/libpamc/test/regress/test.libpamc.c b/contrib/libpam/libpamc/test/regress/test.libpamc.c
new file mode 100644
index 000000000000..b7bc4e4bca75
--- /dev/null
+++ b/contrib/libpam/libpamc/test/regress/test.libpamc.c
@@ -0,0 +1,342 @@
+/*
+ * This is a small test program for testing libpamc against the
+ * secret@here agent. It does the same as the test.secret@here perl
+ * script in this directory, but via the libpamc API.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <security/pam_client.h>
+#include <ctype.h>
+
+struct internal_packet {
+ int length;
+ int at;
+ char *buffer;
+};
+
+
+void append_data(struct internal_packet *packet, int extra, const char *data)
+{
+ if ((extra + packet->at) >= packet->length) {
+ if (packet->length == 0) {
+ packet->length = 1000;
+ }
+ /* make sure we have at least a char extra space available */
+ while (packet->length <= (extra + packet->at)) {
+ packet->length <<= 1;
+ }
+ packet->buffer = realloc(packet->buffer, packet->length);
+ if (packet->buffer == NULL) {
+ fprintf(stderr, "out of memory\n");
+ exit(1);
+ }
+ }
+
+ if (data != NULL) {
+ memcpy(packet->at + packet->buffer, data, extra);
+ }
+ packet->at += extra;
+
+ /* assisting string manipulation */
+ packet->buffer[packet->at] = '\0';
+}
+
+void append_string(struct internal_packet *packet, const char *string,
+ int with_nul)
+{
+ append_data(packet, strlen(string) + (with_nul ? 1:0), string);
+}
+
+char *identify_secret(char *identity)
+{
+ struct internal_packet temp_packet;
+ FILE *secrets;
+ int length_id;
+
+ temp_packet.length = temp_packet.at = 0;
+ temp_packet.buffer = NULL;
+
+ append_string(&temp_packet, "/home/", 0);
+ append_string(&temp_packet, getlogin(), 0);
+ append_string(&temp_packet, "/.secret@here", 1);
+
+ secrets = fopen(temp_packet.buffer, "r");
+ if (secrets == NULL) {
+ fprintf(stderr, "server: failed to open\n [%s]\n",
+ temp_packet.buffer);
+ exit(1);
+ }
+
+ length_id = strlen(identity);
+ for (;;) {
+ char *secret = NULL;
+ temp_packet.at = 0;
+
+ if (fgets(temp_packet.buffer, temp_packet.length, secrets) == NULL) {
+ fclose(secrets);
+ return NULL;
+ }
+
+ if (memcmp(temp_packet.buffer, identity, length_id)) {
+ continue;
+ }
+
+ fclose(secrets);
+ for (secret=temp_packet.buffer; *secret; ++secret) {
+ if (*secret == ' ' || *secret == '\n' || *secret == '\t') {
+ break;
+ }
+ }
+ for (; *secret; ++secret) {
+ if (!(*secret == ' ' || *secret == '\n' || *secret == '\t')) {
+ break;
+ }
+ }
+
+ for (temp_packet.buffer=secret; *temp_packet.buffer;
+ ++temp_packet.buffer) {
+ if (*temp_packet.buffer == ' ' || *temp_packet.buffer == '\n'
+ || *temp_packet.buffer == '\t') {
+ break;
+ }
+ }
+ if (*temp_packet.buffer) {
+ *temp_packet.buffer = '\0';
+ }
+
+ return secret;
+ }
+
+ /* NOT REACHED */
+}
+
+/*
+ * This is a hack, and is fundamentally insecure. All our secrets will be
+ * displayed on the command line for someone doing 'ps' to see. This
+ * is just for programming convenience in this instance, since this
+ * program is simply a regression test. The pam_secret module should
+ * not do this, but make use of md5 routines directly.
+ */
+
+char *create_digest(int length, const char *raw)
+{
+ struct internal_packet temp_packet;
+ FILE *pipe;
+
+ temp_packet.length = temp_packet.at = 0;
+ temp_packet.buffer = NULL;
+
+ append_string(&temp_packet, "echo -n '", 0);
+ append_string(&temp_packet, raw, 0);
+ append_string(&temp_packet, "'|/usr/bin/md5sum -", 1);
+
+ fprintf(stderr, "am attempting to run [%s]\n", temp_packet.buffer);
+
+ pipe = popen(temp_packet.buffer, "r");
+ if (pipe == NULL) {
+ fprintf(stderr, "server: failed to run\n [%s]\n", temp_packet.buffer);
+ exit(1);
+ }
+
+ temp_packet.at = 0;
+ append_data(&temp_packet, 32, NULL);
+
+ if (fgets(temp_packet.buffer, 33, pipe) == NULL) {
+ fprintf(stderr, "server: failed to read digest\n");
+ exit(1);
+ }
+ if (strlen(temp_packet.buffer) != 32) {
+ fprintf(stderr, "server: digest was not 32 chars?? [%s]\n",
+ temp_packet.buffer);
+ exit(1);
+ }
+
+ fclose(pipe);
+
+ return temp_packet.buffer;
+}
+
+void packet_to_prompt(pamc_bp_t *prompt_p, __u8 control,
+ struct internal_packet *packet)
+{
+ PAM_BP_RENEW(prompt_p, control, packet->at);
+ PAM_BP_FILL(*prompt_p, 0, packet->at, packet->buffer);
+ packet->at = 0;
+}
+
+void prompt_to_packet(pamc_bp_t prompt, struct internal_packet *packet)
+{
+ int data_length;
+
+ data_length = PAM_BP_LENGTH(prompt);
+ packet->at = 0;
+ append_data(packet, data_length, NULL);
+
+ PAM_BP_EXTRACT(prompt, 0, data_length, packet->buffer);
+
+ fprintf(stderr, "server received[%d]: {%d|0x%.2x|%s}\n",
+ data_length,
+ PAM_BP_SIZE(prompt), PAM_BP_RCONTROL(prompt),
+ PAM_BP_RDATA(prompt));
+}
+
+int main(int argc, char **argv)
+{
+ pamc_handle_t pch;
+ pamc_bp_t prompt = NULL;
+ struct internal_packet packet_data, *packet;
+ char *temp_string, *secret, *user, *a_cookie, *seqid, *digest;
+ const char *cookie = "123451234512345";
+ int retval;
+
+ packet = &packet_data;
+ packet->length = 0;
+ packet->at = 0;
+ packet->buffer = NULL;
+
+ pch = pamc_start();
+ if (pch == NULL) {
+ fprintf(stderr, "server: unable to get a handle from libpamc\n");
+ exit(1);
+ }
+
+ temp_string = getlogin();
+ if (temp_string == NULL) {
+ fprintf(stderr, "server: who are you?\n");
+ exit(1);
+ }
+#define DOMAIN "@local.host"
+ user = malloc(1+strlen(temp_string)+strlen(DOMAIN));
+ if (user == NULL) {
+ fprintf(stderr, "server: out of memory for user id\n");
+ exit(1);
+ }
+ sprintf(user, "%s%s", temp_string, DOMAIN);
+
+ append_string(packet, "secret@here/", 0);
+ append_string(packet, user, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, cookie, 0);
+ packet_to_prompt(&prompt, PAM_BPC_SELECT, packet);
+
+ /* get the library to accept the first packet (which should load
+ the secret@here agent) */
+
+ retval = pamc_converse(pch, &prompt);
+ fprintf(stderr, "server: after conversation\n");
+ if (PAM_BP_RCONTROL(prompt) != PAM_BPC_OK) {
+ fprintf(stderr, "server: prompt had unexpected control type: %u\n",
+ PAM_BP_RCONTROL(prompt));
+ exit(1);
+ }
+
+ fprintf(stderr, "server: got a prompt back\n");
+
+ prompt_to_packet(prompt, packet);
+
+ temp_string = strtok(packet->buffer, "|");
+ if (temp_string == NULL) {
+ fprintf(stderr, "server: prompt does not contain anything");
+ exit(1);
+ }
+ seqid = strdup(temp_string);
+ if (seqid == NULL) {
+ fprintf(stderr, "server: unable to store sequence id\n");
+ }
+
+ temp_string = strtok(NULL, "|");
+ if (temp_string == NULL) {
+ fprintf(stderr, "server: no cookie from agent\n");
+ exit(1);
+ }
+ a_cookie = strdup(temp_string);
+ if (a_cookie == NULL) {
+ fprintf(stderr, "server: no memory to store agent cookie\n");
+ exit(1);
+ }
+
+ fprintf(stderr, "server: agent responded with {%s|%s}\n", seqid, a_cookie);
+ secret = identify_secret(user);
+ fprintf(stderr, "server: secret=%s\n", secret);
+
+ /* now, we construct the response */
+ packet->at = 0;
+ append_string(packet, a_cookie, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, cookie, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, secret, 0);
+
+ fprintf(stderr, "server: get digest of %s\n", packet->buffer);
+
+ digest = create_digest(packet->at, packet->buffer);
+
+ fprintf(stderr, "server: secret=%s, digest=%s\n", secret, digest);
+
+ packet->at = 0;
+ append_string(packet, seqid, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, digest, 0);
+ packet_to_prompt(&prompt, PAM_BPC_OK, packet);
+
+ retval = pamc_converse(pch, &prompt);
+ fprintf(stderr, "server: after 2nd conversation\n");
+ if (PAM_BP_RCONTROL(prompt) != PAM_BPC_DONE) {
+ fprintf(stderr, "server: 2nd prompt had unexpected control type: %u\n",
+ PAM_BP_RCONTROL(prompt));
+ exit(1);
+ }
+
+ prompt_to_packet(prompt, packet);
+ PAM_BP_RENEW(&prompt, 0, 0);
+
+ temp_string = strtok(packet->buffer, "|");
+ if (temp_string == NULL) {
+ fprintf(stderr, "no digest from agent\n");
+ exit(1);
+ }
+ temp_string = strdup(temp_string);
+
+ packet->at = 0;
+ append_string(packet, secret, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, cookie, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, a_cookie, 0);
+
+ fprintf(stderr, "server: get digest of %s\n", packet->buffer);
+
+ digest = create_digest(packet->at, packet->buffer);
+
+ fprintf(stderr, "server: digest=%s\n", digest);
+
+ if (strcmp(digest, temp_string)) {
+ fprintf(stderr, "server: agent doesn't know the secret\n");
+ fprintf(stderr, "server: agent says: [%s]\n"
+ "server: server says: [%s]\n", temp_string, digest);
+ exit(1);
+ } else {
+ fprintf(stderr, "server: agent seems to know the secret\n");
+
+ packet->at = 0;
+ append_string(packet, cookie, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, secret, 0);
+ append_string(packet, "|", 0);
+ append_string(packet, a_cookie, 0);
+
+ digest = create_digest(packet->at, packet->buffer);
+
+ fprintf(stderr, "server: putenv(\"AUTH_SESSION_TICKET=%s\")\n",
+ digest);
+ }
+
+
+ retval = pamc_end(&pch);
+
+ fprintf(stderr, "server: agent(s) were %shappy to terminate\n",
+ retval == PAM_BPC_TRUE ? "":"un");
+
+ exit(!retval);
+}
diff --git a/contrib/libpam/libpamc/test/regress/test.secret@here b/contrib/libpam/libpamc/test/regress/test.secret@here
new file mode 100755
index 000000000000..2e0b9b940cb6
--- /dev/null
+++ b/contrib/libpam/libpamc/test/regress/test.secret@here
@@ -0,0 +1,152 @@
+#!/usr/bin/perl
+
+##
+## this is a test script for regressing changes to the secret@here PAM
+## agent
+##
+
+$^W = 1;
+use strict;
+use IPC::Open2;
+
+$| = 1;
+
+my $whoami = `/usr/bin/whoami`; chomp $whoami;
+my $cookie = "12345";
+my $user_domain = "$whoami\@local.host";
+
+my $pid = open2(\*Reader, \*Writer, "../agents/secret\@here blah")
+ or die "failed to load secret\@here agent";
+
+unless (-f (getpwuid($<))[7]."/.secret\@here") {
+ print STDERR "server: ". "no " .(getpwuid($<))[7]. "/.secret\@here file\n";
+ die "no config file";
+}
+
+WriteBinaryPrompt(\*Writer, 0x02, "secret\@here/$user_domain|$cookie");
+
+my ($control, $data) = ReadBinaryPrompt(\*Reader);
+
+print STDERR "server: ". "reply: control=$control, data=$data\n";
+if ($control != 1) {
+ die "expected 1 (OK) for the first agent reply; got $control";
+}
+my ($seqid, $a_cookie) = split '\|', $data;
+
+# server needs to convince agent that it knows the secret before
+# agent will give a valid response
+my $secret = IdentifyLocalSecret($user_domain);
+my $digest = CreateDigest($a_cookie."|".$cookie."|".$secret);
+
+print STDERR "server: ". "digest = $digest\n";
+WriteBinaryPrompt(\*Writer, 0x01, "$seqid|$digest");
+
+# The agent will authenticate us and then reply with its
+# authenticating digest. we check that before we're done.
+
+($control, $data) = ReadBinaryPrompt(\*Reader);
+if ($control != 0x03) {
+ die "server: agent did not reply with a 'done' prompt ($control)\n";
+}
+
+unless ($data eq CreateDigest($secret."|".$cookie."|".$a_cookie)) {
+ die "server: agent is not authenticated\n";
+}
+
+print STDERR "server: agent appears to know secret\n";
+
+my $session_authenticated_ticket
+ = CreateDigest($cookie."|".$secret."|".$a_cookie);
+
+print STDERR "server: should putenv("
+ ."\"AUTH_SESSION_TICKET=$session_authenticated_ticket\")\n";
+
+exit 0;
+
+sub CreateDigest ($) {
+ my ($data) = @_;
+
+ my $pid = open2(\*MD5out, \*MD5in, "/usr/bin/md5sum -")
+ or die "you'll need /usr/bin/md5sum installed";
+
+ my $oldfd = select MD5in; $|=1; select $oldfd;
+ print MD5in "$data";
+ close MD5in;
+ my $reply = <MD5out>;
+ ($reply) = split /\s/, $reply;
+ print STDERR "server: ". "md5 said: <$reply>\n";
+ close MD5out;
+
+ return $reply;
+}
+
+sub ReadBinaryPrompt ($) {
+ my ($fd) = @_;
+
+ my $buffer = " ";
+ my $count = read($fd, $buffer, 5);
+ if ($count == 0) {
+ # no more packets to read
+ return (0, "");
+ }
+
+ if ($count != 5) {
+ # broken packet header
+ return (-1, "");
+ }
+
+ my ($length, $control) = unpack("N C", $buffer);
+ if ($length < 5) {
+ # broken packet length
+ return (-1, "");
+ }
+
+ my $data = "";
+ $length -= 5;
+ while ($count = read($fd, $buffer, $length)) {
+ $data .= $buffer;
+ if ($count != $length) {
+ $length -= $count;
+ next;
+ }
+
+ print STDERR "server: ". "data is [$data]\n";
+
+ return ($control, $data);
+ }
+
+ # broken packet data
+ return (-1, "");
+}
+
+sub WriteBinaryPrompt ($$$) {
+ my ($fd, $control, $data) = @_;
+
+ my $length = 5 + length($data);
+ printf STDERR "server: ". "{%d|0x%.2x|%s}\n", $length, $control, $data;
+ my $bp = pack("N C a*", $length, $control, $data);
+ print $fd $bp;
+
+ print STDERR "server: ". "control passed to agent\@here\n";
+}
+
+sub IdentifyLocalSecret ($) {
+ my ($identifier) = @_;
+ my $secret;
+
+ my $whoami = `/usr/bin/whoami` ; chomp $whoami;
+ if (open SECRETS, "< " .(getpwuid($<))[7]. "/.secret\@here") {
+ my $line;
+ while (defined ($line = <SECRETS>)) {
+ my ($id, $sec) = split /[\s]/, $line;
+ if ((defined $id) && ($id eq $identifier)) {
+ $secret = $sec;
+ last;
+ }
+ }
+ close SECRETS;
+ }
+
+ return $secret;
+}
+
diff --git a/contrib/libpam/modules/Makefile b/contrib/libpam/modules/Makefile
index 0066fb473e0c..aece2068904c 100644
--- a/contrib/libpam/modules/Makefile
+++ b/contrib/libpam/modules/Makefile
@@ -1,89 +1,17 @@
-# $Id: Makefile,v 1.21 1997/04/05 06:44:43 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# Makefile
#
# This makefile controls the build process of shared and static PAM modules.
#
-# $Log: Makefile,v $
-# Revision 1.21 1997/04/05 06:44:43 morgan
-# pam_env and pam_tally added
-#
-# Revision 1.20 1997/02/15 18:57:11 morgan
-# fixed bash syntax
-#
-# Revision 1.19 1997/01/04 20:21:32 morgan
-# moved responsibility of conditional compilation to modules (more flexible)
-#
-# Revision 1.18 1996/12/01 03:34:40 morgan
-# update for .54
-#
-# Revision 1.17 1996/11/10 20:20:15 morgan
-# cross platform support and new modules
-#
-# Revision 1.16 1996/09/05 06:20:45 morgan
-# added two modules: listfile and shells
-#
-# Revision 1.15 1996/08/09 05:38:28 morgan
-# added new/proposed modules.
-# fixed makefile installation dependencies
-#
-# Revision 1.14 1996/07/08 00:00:33 morgan
-# added wheel and group modules
#
-MODDIRS=\
- pam_access \
- pam_afs \
- pam_afsauth \
- pam_afspass \
- pam_afstok \
- pam_cracklib \
- pam_deny \
- pam_desgold \
- pam_env \
- pam_filter \
- pam_ftp \
- pam_group \
- pam_kerberos \
- pam_krb4 \
- pam_lastlog \
- pam_listfile \
- pam_limits \
- pam_mail \
- pam_nologin \
- pam_opie \
- pam_passwd+ \
- pam_permit \
- pam_pwdb \
- pam_radius \
- pam_restrict \
- pam_rhosts \
- pam_rootok \
- pam_securetty \
- pam_shells \
- pam_sid \
- pam_skey \
- pam_skey2 \
- pam_stress \
- pam_syslog \
- pam_tally \
- pam_time \
- pam_unix \
- pam_warn \
- pam_wheel
+include ../Make.Rules
-
-# ////////////////////////////////////////////////////
-# // You should not modify anything below this line //
-# ////////////////////////////////////////////////////
-
-dummy:
- @echo "*** This is not a top-level Makefile! ***"
-
-# -----------------------------------------------------------
+MODDIRS=$(shell /bin/ls -d pam_*)
all:
- @echo modules for $(OS) are:
+ @echo modules sources available are:
@ls -d $(MODDIRS) 2>/dev/null ; echo :--------
@echo
ifdef STATIC
@@ -98,6 +26,9 @@ endif
} fi ; \
done
+download:
+ @./download-all
+
install:
for i in $(MODDIRS) ; do \
if [ -d $$i ]; then { \
@@ -123,10 +54,3 @@ clean: lclean
} fi ; \
done
-extraclean: lclean
- for i in $(MODDIRS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i extraclean ; \
- fi ; \
- done
-
diff --git a/contrib/libpam/modules/README b/contrib/libpam/modules/README
index 864159478c65..73d3cf0c2e49 100644
--- a/contrib/libpam/modules/README
+++ b/contrib/libpam/modules/README
@@ -1,7 +1,7 @@
This directory contains the modules.
If you want to reserve a module name please email <pam-list@redhat.com>
-and announce its name. Andrew Morgan, <morgan@parc.power.net>, will
+and announce its name. Andrew Morgan, <morgan@linux.kernel.org>, will
add it to the Makefile in the next release of Linux-PAM.
As of Linux-PAM-0.40 modules can optionally conform to the static
diff --git a/contrib/libpam/modules/Simple.Rules b/contrib/libpam/modules/Simple.Rules
new file mode 100644
index 000000000000..954641c668a3
--- /dev/null
+++ b/contrib/libpam/modules/Simple.Rules
@@ -0,0 +1,92 @@
+# $Id: Simple.Rules,v 1.3 2001/02/22 04:55:41 agmorgan Exp $
+#
+# For simple modules with no significant dependencies, set $(TITLE)
+# and include this file.
+#
+# There are a few ways to customize this set of rules. Namely, define
+#
+# $(MODULE_SIMPLE_EXTRACLEAN)
+# $(MODULE_SIMPLE_CLEAN)
+# $(MODULE_SIMPLE_REMOVE)
+# $(MODULE_SIMPLE_INSTALL)
+# $(MODULE_SIMPLE_EXTRALIBS) - other things to link with the module
+# $(MODULE_SIMPLE_EXTRAFILES) - other files to build (no .c suffix)
+#
+
+LIBFILES = $(TITLE) $(MODULE_SIMPLE_EXTRAFILES)
+LIBSRC = $(addsuffix .c,$(LIBFILES))
+LIBOBJ = $(addsuffix .o,$(LIBFILES))
+LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
+LIBOBJS = $(addprefix static/,$(LIBOBJ))
+
+ifdef DYNAMIC
+LIBSHARED = $(TITLE).so
+endif
+
+ifdef STATIC
+LIBSTATIC = lib$(TITLE).o
+endif
+
+####################### don't edit below #######################
+
+all: dirs $(LIBSHARED) $(LIBSTATIC) register
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(DYNAMIC) $(TARGET_ARCH) -c $< -o $@
+
+static/%.o : %.c
+ $(CC)