aboutsummaryrefslogtreecommitdiff
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) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
+
+dirs:
+ifdef DYNAMIC
+ $(MKDIR) ./dynamic
+endif
+ifdef STATIC
+ $(MKDIR) ./static
+endif
+
+register:
+ifdef STATIC
+ ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+endif
+
+ifdef DYNAMIC
+$(LIBOBJD): $(LIBSRC)
+endif
+
+ifdef DYNAMIC
+$(LIBSHARED): $(LIBOBJD)
+ $(LD_D) -o $@ $(LIBOBJD) $(MODULE_SIMPLE_EXTRALIBS) $(NEED_LINK_LIB_C)
+
+endif
+
+ifdef STATIC
+$(LIBOBJS): $(LIBSRC)
+endif
+
+ifdef STATIC
+$(LIBSTATIC): $(LIBOBJS)
+ $(LD) -r -o $@ $(LIBOBJS) $(MODULE_SIMPLE_EXTRALIBS)
+endif
+
+install: all
+ $(MKDIR) $(FAKEROOT)$(SECUREDIR)
+ifdef DYNAMIC
+ $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
+endif
+ $(MODULE_SIMPLE_INSTALL)
+
+remove:
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ $(MODULE_SIMPLE_REMOVE)
+
+clean:
+ rm -f $(LIBOBJD) $(LIBOBJS) core *~
+ $(MODULE_SIMPLE_CLEAN)
+ rm -f *.a *.o *.so *.bak
+ rm -rf dynamic static
+ $(MODULE_SIMPLE_EXTRACLEAN)
+
+.c.o:
+ $(CC) $(CFLAGS) -c $<
+
diff --git a/contrib/libpam/modules/dont_makefile b/contrib/libpam/modules/dont_makefile
index f256ce1b3a61..48307f02ecd4 100644
--- a/contrib/libpam/modules/dont_makefile
+++ b/contrib/libpam/modules/dont_makefile
@@ -1,4 +1,6 @@
#########################################################################
+# $Id: dont_makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
+#########################################################################
# This is a makefile that does nothing. It is designed to be included
# by module Makefile-s when they are not compatable with the local
# system
@@ -7,7 +9,7 @@
all:
@echo "This module will not be compiled on this system"
-extraclean: clean
+remove: clean
install: clean
diff --git a/contrib/libpam/modules/download-all b/contrib/libpam/modules/download-all
new file mode 100755
index 000000000000..9b6cf6558136
--- /dev/null
+++ b/contrib/libpam/modules/download-all
@@ -0,0 +1,30 @@
+#!/bin/sh
+#
+# $Id: download-all,v 1.1.1.1 2000/06/20 22:11:29 agmorgan Exp $
+#
+cat <<EOT
+For a number of reasons it is not practical for Linux-PAM to be
+distributed with every module out there. However, this shell script
+is intended as a convenient way for users to download modules from the
+'net in some semiautomated fashion.
+
+Please feel free to send (pam-list@redhat.com) snippets of code that
+will help others to download and unpack your favorite module into the
+Linux-PAM source tree. Especially welcome are snippets of the
+following form:
+
+ncftp ftp://my.ftpsite.org/pub/fluff/pam_fluff.tar.gz
+rm -fr pam_fluff
+tar zvfx pam_fluff.tar.gz
+
+Cheers
+
+Andrew
+morgan@linux.kernel.org
+EOT
+
+# --- insert your snippets below ---
+
+# --- insert your snippets above ---
+
+exit 0
diff --git a/contrib/libpam/modules/install_conf b/contrib/libpam/modules/install_conf
new file mode 100755
index 000000000000..80f6be292d19
--- /dev/null
+++ b/contrib/libpam/modules/install_conf
@@ -0,0 +1,49 @@
+#!/bin/bash
+
+FAKEROOT=$1
+CONFD=$1$2
+CONFILE=$1$3
+MODULE=$4
+CONF=$5
+
+IGNORE_AGE=./.ignore_age
+QUIET_INSTALL=../../.quiet_install
+
+echo
+
+if [ -f "$QUIET_INSTALL" ]; then
+ if [ ! -f "$CONFILE" ]; then
+ yes="y"
+ else
+ yes="skip"
+ fi
+elif [ -f "$IGNORE_AGE" ]; then
+ echo "you don't want to be bothered with the age of your $CONFILE file"
+ yes="n"
+elif [ ! -f "$CONFILE" ] || [ "$CONF" -nt "$CONFILE" ]; then
+ if [ -f "$CONFILE" ]; then
+ echo "An older $MODULE configuration file already exists ($CONFILE)"
+ echo "Do you wish to copy the $CONF file in this distribution"
+ echo "to $CONFILE ? (y/n) [skip] "
+ read yes
+ else
+ yes="y"
+ fi
+else
+ yes="skip"
+fi
+
+if [ "$yes" = "y" ]; then
+ mkdir -p $CONFD
+ echo " copying $CONF to $CONFILE"
+ cp $CONF $CONFILE
+else
+ echo " Skipping $CONF installation"
+ if [ "$yes" = "n" ]; then
+ touch "$IGNORE_AGE"
+ fi
+fi
+
+echo
+
+exit 0
diff --git a/contrib/libpam/modules/pam_access/Makefile b/contrib/libpam/modules/pam_access/Makefile
index a3d684bb7179..88c02fee7b54 100644
--- a/contrib/libpam/modules/pam_access/Makefile
+++ b/contrib/libpam/modules/pam_access/Makefile
@@ -1,111 +1,21 @@
-# $Id: Makefile,v 1.1 1997/06/23 00:39:42 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.1 1997/06/23 00:39:42 morgan
-# Initial revision
-#
-#
-
-TITLE=pam_access
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/access.conf
-export CONFILE
-
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
+TITLE=pam_access
+LOCAL_CONFILE=./access.conf
+INSTALLED_CONFILE=$(SCONFIGD)/access.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_access/README b/contrib/libpam/modules/pam_access/README
index df10c269ec04..ddd4725f0e04 100644
--- a/contrib/libpam/modules/pam_access/README
+++ b/contrib/libpam/modules/pam_access/README
@@ -1,4 +1,8 @@
-# Description of its configuration file (/etc/security/access.conf):
+# Description of its configuration file
+#
+# (The default config file is "/etc/security/access.conf". This
+# default can be overridden with a module config argument
+# 'accessfile=<full-path>'):
#
# Login access control table.
#
diff --git a/contrib/libpam/modules/pam_access/pam_access.c b/contrib/libpam/modules/pam_access/pam_access.c
index 121333928a26..87ad708d81ed 100644
--- a/contrib/libpam/modules/pam_access/pam_access.c
+++ b/contrib/libpam/modules/pam_access/pam_access.c
@@ -5,12 +5,27 @@
* (I took login_access from logdaemon-5.6 and converted it to PAM
* using parts of pam_time code.)
*
+ ************************************************************************
+ * Copyright message from logdaemon-5.6 (original file name DISCLAIMER)
+ ************************************************************************
+ * Copyright 1995 by Wietse Venema. All rights reserved. Individual files
+ * may be covered by other copyrights (as noted in the file itself.)
+ *
+ * This material was originally written and compiled by Wietse Venema at
+ * Eindhoven University of Technology, The Netherlands, in 1990, 1991,
+ * 1992, 1993, 1994 and 1995.
+ *
+ * Redistribution and use in source and binary forms are permitted
+ * provided that this entire copyright notice is duplicated in all such
+ * copies.
+ *
+ * This software is provided "as is" and without any expressed or implied
+ * warranties, including, without limitation, the implied warranties of
+ * merchantibility and fitness for any particular purpose.
+ *************************************************************************
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -46,21 +61,6 @@ extern int gethostname(char *name, size_t len);
#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-/* --- static functions for checking whether the user should be let in --- */
-
-static void _log_err(const char *format, ... )
-{
- va_list args;
-
- va_start(args, format);
- openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(LOG_ERR, format, args);
- va_end(args);
- closelog();
-}
-
-#define PAM_ACCESS_CONFIG CONFILE
-
int strcasecmp(const char *s1, const char *s2);
/* login_access.c from logdaemon-5.6 with several changes by A.Nogin: */
@@ -79,10 +79,16 @@ int strcasecmp(const char *s1, const char *s2);
#define MAXHOSTNAMELEN 256
#endif
+#ifdef DEFAULT_CONF_FILE
+# define PAM_ACCESS_CONFIG DEFAULT_CONF_FILE
+#else
+# define PAM_ACCESS_CONFIG "/etc/security/access.conf"
+#endif
+
/* Delimiters for fields and for lists of users, ttys or hosts. */
-static char fs[] = ":"; /* field separator */
-static char sep[] = ", \t"; /* list-element separator */
+static const char fs[] = ":"; /* field separator */
+static const char sep[] = ", \t"; /* list-element separator */
/* Constants to be used in assignments only, not in comparisons... */
@@ -96,8 +102,50 @@ static char sep[] = ", \t"; /* list-element separator */
struct login_info {
struct passwd *user;
char *from;
+ const char *config_file;
+ const char *service;
};
+/* --- static functions for checking whether the user should be let in --- */
+
+static void _log_err(const char *format, ... )
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("pam_access", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(LOG_ERR, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* Parse module config arguments */
+
+static int parse_args(struct login_info *loginfo, int argc, const char **argv)
+{
+ int i;
+
+ for (i=0; i<argc; ++i) {
+ if (!strncmp("accessfile=", argv[i], 11)) {
+ FILE *fp = fopen(11 + argv[i], "r");
+
+ if (fp) {
+ loginfo->config_file = 11 + argv[i];
+ fclose(fp);
+ } else {
+ _log_err("for service [%s] failed to open accessfile=[%s]"
+ , loginfo->service, 11 + argv[i]);
+ return 0;
+ }
+
+ } else {
+ _log_err("unrecognized option [%s]", argv[i]);
+ }
+ }
+
+ return 1; /* OK */
+}
+
typedef int match_func (char *, struct login_info *);
static int list_match (char *, struct login_info *,
@@ -108,23 +156,16 @@ static int string_match (char *, char *);
/* login_access - match username/group and host/tty with access control file */
-static int login_access(struct passwd *user, char *from)
+static int login_access(struct login_info *item)
{
- struct login_info item;
FILE *fp;
char line[BUFSIZ];
- char *perm; /* becomes permission field */
- char *users; /* becomes list of login names */
- char *froms; /* becomes list of terminals or hosts */
+ char *perm; /* becomes permission field */
+ char *users; /* becomes list of login names */
+ char *froms; /* becomes list of terminals or hosts */
int match = NO;
int end;
- int lineno = 0; /* for diagnostics */
-
- /*
- * Bundle up the arguments to avoid unnecessary clumsiness lateron.
- */
- item.user = user;
- item.from = from;
+ int lineno = 0; /* for diagnostics */
/*
* Process the table one line at a time and stop at the first match.
@@ -134,12 +175,12 @@ static int login_access(struct passwd *user, char *from)
* non-existing table means no access control.
*/
- if ((fp = fopen(PAM_ACCESS_CONFIG, "r"))!=NULL) {
+ if ((fp = fopen(item->config_file, "r"))!=NULL) {
while (!match && fgets(line, sizeof(line), fp)) {
lineno++;
if (line[end = strlen(line) - 1] != '\n') {
_log_err("%s: line %d: missing newline or line too long",
- PAM_ACCESS_CONFIG, lineno);
+ item->config_file, lineno);
continue;
}
if (line[0] == '#')
@@ -153,19 +194,21 @@ static int login_access(struct passwd *user, char *from)
|| !(users = strtok((char *) 0, fs))
|| !(froms = strtok((char *) 0, fs))
|| strtok((char *) 0, fs)) {
- _log_err("%s: line %d: bad field count", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad field count",
+ item->config_file, lineno);
continue;
}
if (perm[0] != '+' && perm[0] != '-') {
- _log_err("%s: line %d: bad first field", PAM_ACCESS_CONFIG, lineno);
+ _log_err("%s: line %d: bad first field",
+ item->config_file, lineno);
continue;
}
- match = (list_match(froms, &item, from_match)
- && list_match(users, &item, user_match));
+ match = (list_match(froms, item, from_match)
+ && list_match(users, item, user_match));
}
(void) fclose(fp);
} else if (errno != ENOENT) {
- _log_err("cannot open %s: %m", PAM_ACCESS_CONFIG);
+ _log_err("cannot open %s: %m", item->config_file);
}
return (match == 0 || (line[0] == '+'));
}
@@ -356,10 +399,17 @@ int strcasecmp(const char *s1, const char *s2)
PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
- const char *user=NULL;
+ struct login_info loginfo;
+ const char *user=NULL, *service=NULL;
char *from=NULL;
struct passwd *user_pw;
+ if ((pam_get_item(pamh, PAM_SERVICE, (const void **)&service)
+ != PAM_SUCCESS) || (service == NULL) || (*service == ' ')) {
+ _log_err("cannot find the service name");
+ return PAM_ABORT;
+ }
+
/* set username */
if (pam_get_user(pamh, &user, NULL) != PAM_SUCCESS || user == NULL
@@ -398,8 +448,27 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t *pamh,int flags,int argc
}
}
+
if ((user_pw=getpwnam(user))==NULL) return (PAM_USER_UNKNOWN);
- if (login_access(user_pw,from)) return (PAM_SUCCESS); else {
+
+ /*
+ * Bundle up the arguments to avoid unnecessary clumsiness later on.
+ */
+ loginfo.user = user_pw;
+ loginfo.from = from;
+ loginfo.service = service;
+ loginfo.config_file = PAM_ACCESS_CONFIG;
+
+ /* parse the argument list */
+
+ if (!parse_args(&loginfo, argc, argv)) {
+ _log_err("failed to parse the module arguments");
+ return PAM_ABORT;
+ }
+
+ if (login_access(&loginfo)) {
+ return (PAM_SUCCESS);
+ } else {
_log_err("access denied for user `%s' from `%s'",user,from);
return (PAM_PERM_DENIED);
}
diff --git a/contrib/libpam/modules/pam_cracklib/Makefile b/contrib/libpam/modules/pam_cracklib/Makefile
index 668f2f846296..371ac0a86c3e 100644
--- a/contrib/libpam/modules/pam_cracklib/Makefile
+++ b/contrib/libpam/modules/pam_cracklib/Makefile
@@ -1,110 +1,32 @@
#
+# $Id: Makefile,v 1.3 2001/02/10 22:15:23 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10
+# Created by Andrew Morgan <morgan@kernel.org> 2000/10/08
#
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-#
-# here you should make default variable defines...
-#
-MKDIR=mkdir -p
-LD_D=gcc -shared -Xlinker -x
-INSTALL=install
-SECUREDIR=/usr/lib/security
-#
-HAVE_CRACKLIB=yes
-endif
-
-ifeq ($(HAVE_CRACKLIB),yes)
+include ../../Make.Rules
TITLE=pam_cracklib
-CRACKLIB=-lcrack
-CRACKLIB_DICTPATH=/usr/lib/cracklib_dict
-#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+ifeq ($(HAVE_LIBCRACK),yes)
+BUILD_THIS_MODULE=yes
+MODULE_SIMPLE_EXTRALIBS=-lcrack
-ifdef CRACKLIB_DICTPATH
+# These two should really be provided by ../../pam_aconf.h
CFLAGS+=-DCRACKLIB_DICTPATH=\"$(CRACKLIB_DICTPATH)\"
-endif
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+ifeq ($(HAVE_LIBCRYPT),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lcrypt
endif
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC) Makefile
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(CRACKLIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
endif
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+ifeq ($(BUILD_THIS_MODULE),yes)
+ include ../Simple.Rules
else
-
-include ../dont_makefile
-
+ include ../dont_makefile
endif
diff --git a/contrib/libpam/modules/pam_cracklib/README b/contrib/libpam/modules/pam_cracklib/README
index e4b02731b523..69662f7385b3 100644
--- a/contrib/libpam/modules/pam_cracklib/README
+++ b/contrib/libpam/modules/pam_cracklib/README
@@ -13,9 +13,25 @@ RECOGNIZED ARGUMENTS:
retry=N Prompt user at most N times before returning with
error. Default N=1.
+ difok=N How many characters can be the same in the new
+ password relative to the old
+ difignore=N How many characters long should the password be
+ before we ignore difok.
+
+ minlen=N The minimum simplicity count for a good password.
+
+ dcredit=N
+ ucredit=N
+ lcredit=N
+ ocredit=N Weight, digits, upper, lower, other characters with
+ count N. Use these values to compute the
+ 'unsimplicity' of the password.
+
+ use_authtok Get the proposed password from PAM_AUTHTOK
+
MODULE SERVICES PROVIDED:
passwd chauthtok
AUTHOR:
- Cristian Gafton <gafton@sorosis.ro>
+ Cristian Gafton <gafton@redhat.com>
diff --git a/contrib/libpam/modules/pam_cracklib/pam_cracklib.c b/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
index 3400dfb25209..07725db7ee7b 100644
--- a/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
+++ b/contrib/libpam/modules/pam_cracklib/pam_cracklib.c
@@ -29,8 +29,12 @@
* S.A.G. in the section on the cracklib module.
*/
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
-#define __USE_BSD
+#ifdef HAVE_CRYPT_H
+# include <crypt.h>
+#endif
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
@@ -43,7 +47,7 @@
extern char *FascistCheck(char *pw, const char *dictpath);
#ifndef CRACKLIB_DICTPATH
-#define CRACKLIB_DICTPATH "/usr/lib/cracklib_dict"
+#define CRACKLIB_DICTPATH "/usr/share/dict/cracklib_dict"
#endif
#define PROMPT1 "New %s password: "
@@ -82,20 +86,31 @@ static void _pam_log(int err, const char *format, ...)
/* argument parsing */
#define PAM_DEBUG_ARG 0x0001
-/* module data - AGM: please remove these static variables... PAM was
- * designed to be reentrant based soley on a unique pamh... this
- * breaks that. */
-
-static int retry_times = 0;
-static int diff_ok = 10;
-static int min_length = 9;
-static int dig_credit = 1;
-static int up_credit = 1;
-static int low_credit = 1;
-static int oth_credit = 1;
-static char prompt_type[BUFSIZ];
+struct cracklib_options {
+ int retry_times;
+ int diff_ok;
+ int diff_ignore;
+ int min_length;
+ int dig_credit;
+ int up_credit;
+ int low_credit;
+ int oth_credit;
+ int use_authtok;
+ char prompt_type[BUFSIZ];
+};
-static int _pam_parse(int argc, const char **argv)
+#define CO_RETRY_TIMES 1
+#define CO_DIFF_OK 10
+#define CO_DIFF_IGNORE 23
+#define CO_MIN_LENGTH 9
+# define CO_MIN_LENGTH_BASE 5
+#define CO_DIG_CREDIT 1
+#define CO_UP_CREDIT 1
+#define CO_LOW_CREDIT 1
+#define CO_OTH_CREDIT 1
+#define CO_USE_AUTHTOK 0
+
+static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv)
{
int ctrl=0;
@@ -108,35 +123,41 @@ static int _pam_parse(int argc, const char **argv)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
else if (!strncmp(*argv,"type=",5))
- strcpy(prompt_type, *argv+5);
+ strcpy(opt->prompt_type, *argv+5);
else if (!strncmp(*argv,"retry=",6)) {
- retry_times = strtol(*argv+6,&ep,10);
- if (!ep || (retry_times < 1))
- retry_times = 1;
+ opt->retry_times = strtol(*argv+6,&ep,10);
+ if (!ep || (opt->retry_times < 1))
+ opt->retry_times = CO_RETRY_TIMES;
} else if (!strncmp(*argv,"difok=",6)) {
- diff_ok = strtol(*argv+6,&ep,10);
- if (!ep || (diff_ok < 0))
- diff_ok = 10;
+ opt->diff_ok = strtol(*argv+6,&ep,10);
+ if (!ep || (opt->diff_ok < 0))
+ opt->diff_ok = CO_DIFF_OK;
+ } else if (!strncmp(*argv,"difignore=",10)) {
+ opt->diff_ignore = strtol(*argv+10,&ep,10);
+ if (!ep || (opt->diff_ignore < 0))
+ opt->diff_ignore = CO_DIFF_IGNORE;
} else if (!strncmp(*argv,"minlen=",7)) {
- min_length = strtol(*argv+7,&ep,10);
- if (!ep || (min_length < 5))
- min_length = 5;
+ opt->min_length = strtol(*argv+7,&ep,10);
+ if (!ep || (opt->min_length < CO_MIN_LENGTH_BASE))
+ opt->min_length = CO_MIN_LENGTH_BASE;
} else if (!strncmp(*argv,"dcredit=",8)) {
- dig_credit = strtol(*argv+8,&ep,10);
- if (!ep || (dig_credit < 0))
- dig_credit = 0;
+ opt->dig_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->dig_credit < 0))
+ opt->dig_credit = 0;
} else if (!strncmp(*argv,"ucredit=",8)) {
- up_credit = strtol(*argv+8,&ep,10);
- if (!ep || (up_credit < 0))
- up_credit = 0;
+ opt->up_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->up_credit < 0))
+ opt->up_credit = 0;
} else if (!strncmp(*argv,"lcredit=",8)) {
- low_credit = strtol(*argv+8,&ep,10);
- if (!ep || (low_credit < 0))
- low_credit = 0;
+ opt->low_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->low_credit < 0))
+ opt->low_credit = 0;
} else if (!strncmp(*argv,"ocredit=",8)) {
- oth_credit = strtol(*argv+8,&ep,10);
- if (!ep || (oth_credit < 0))
- oth_credit = 0;
+ opt->oth_credit = strtol(*argv+8,&ep,10);
+ if (!ep || (opt->oth_credit < 0))
+ opt->oth_credit = 0;
+ } else if (!strncmp(*argv,"use_authtok",11)) {
+ opt->use_authtok = 1;
} else {
_pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
}
@@ -216,32 +237,36 @@ static int palindrome(const char *old, const char *new)
}
/*
- * more than half of the characters are different ones.
- * or at least diff_ok are different
- * NOTE that the defaults are NOT the same as befor this
- * change. as long as there are at least 10 different bytes
- * in a new password it will now pass even if the password
- * is longer than 20 bytes (MD5)
+ * This is a reasonably severe check for a different selection of characters
+ * in the old and new passwords.
*/
-static int similiar(const char *old, const char *new)
+static int similar(struct cracklib_options *opt,
+ const char *old, const char *new)
{
- int i, j;
+ int i, j;
- for (i = j = 0;new[i] && old[i];i++)
- if (strchr (new, old[i]))
- j++;
+ for (i = j = 0; old[i]; i++) {
+ if (strchr (new, old[i])) {
+ j++;
+ }
+ }
- if (j >= diff_ok || i >= j * 2)
- return 0;
+ if (((i-j) >= opt->diff_ok)
+ || (strlen(new) >= (j * 2))
+ || (strlen(new) >= opt->diff_ignore)) {
+ /* passwords are not very similar */
+ return 0;
+ }
- return 1;
+ /* passwords are too similar */
+ return 1;
}
/*
* a nice mix of characters.
*/
-static int simple(const char *old, const char *new)
+static int simple(struct cracklib_options *opt, const char *old, const char *new)
{
int digits = 0;
int uppers = 0;
@@ -269,19 +294,19 @@ static int simple(const char *old, const char *new)
* defaults cause the effect to be the same as before the change
*/
- if (digits > dig_credit)
- digits = dig_credit;
+ if (digits > opt->dig_credit)
+ digits = opt->dig_credit;
- if (uppers > up_credit)
- uppers = up_credit;
+ if (uppers > opt->up_credit)
+ uppers = opt->up_credit;
- if (lowers > low_credit)
- lowers = low_credit;
+ if (lowers > opt->low_credit)
+ lowers = opt->low_credit;
- if (others > oth_credit)
- others = oth_credit;
+ if (others > opt->oth_credit)
+ others = opt->oth_credit;
- size = min_length;
+ size = opt->min_length;
size -= digits;
size -= uppers;
size -= lowers;
@@ -302,7 +327,7 @@ static char * str_lower(char *string)
return string;
}
-static const char * password_check(const char *old, const char *new)
+static const char * password_check(struct cracklib_options *opt, const char *old, const char *new)
{
const char *msg = NULL;
char *oldmono, *newmono, *wrapped;
@@ -324,10 +349,10 @@ static const char * password_check(const char *old, const char *new)
if (!msg && strcmp(oldmono, newmono) == 0)
msg = "case changes only";
- if (!msg && similiar(oldmono, newmono))
- msg = "is too similiar to the old one";
+ if (!msg && similar(opt, oldmono, newmono))
+ msg = "is too similar to the old one";
- if (!msg && simple(old, new))
+ if (!msg && simple(opt, old, new))
msg = "is too simple";
if (!msg && strstr(wrapped, newmono))
@@ -344,12 +369,51 @@ static const char * password_check(const char *old, const char *new)
}
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+
+static const char * check_old_password(const char *forwho, const char *newpass)
+{
+ static char buf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas;
+ const char *msg = NULL;
+ FILE *opwfile;
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL)
+ return NULL;
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf)-1] = '\0';
+ s_luser = strtok(buf, ":,");
+ s_uid = strtok(NULL, ":,");
+ s_npas = strtok(NULL, ":,");
+ s_pas = strtok(NULL, ":,");
+ while (s_pas != NULL) {
+ if (!strcmp(crypt(newpass, s_pas), s_pas)) {
+ msg = "has been already used";
+ break;
+ }
+ s_pas = strtok(NULL, ":,");
+ }
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ return msg;
+}
+
+
static int _pam_unix_approve_pass(pam_handle_t *pamh,
unsigned int ctrl,
+ struct cracklib_options *opt,
const char *pass_old,
const char *pass_new)
{
const char *msg = NULL;
+ const char *user;
+ int retval;
if (pass_new == NULL || (pass_old && !strcmp(pass_old,pass_new))) {
if (ctrl && PAM_DEBUG_ARG)
@@ -364,7 +428,18 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh,
* if one wanted to hardwire authentication token strength
* checking this would be the place
*/
- msg = password_check(pass_old,pass_new);
+ msg = password_check(opt, pass_old,pass_new);
+ if (!msg) {
+ retval = pam_get_item(pamh, PAM_USER, (const void **)&user);
+ if (retval != PAM_SUCCESS) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_ERR,"Can not get username");
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+ msg = check_old_password(user, pass_new);
+ }
+
if (msg) {
char remark[BUFSIZ];
@@ -387,14 +462,24 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
int argc, const char **argv)
{
unsigned int ctrl;
+ struct cracklib_options options;
+
+ options.retry_times = CO_RETRY_TIMES;
+ options.diff_ok = CO_DIFF_OK;
+ options.diff_ignore = CO_DIFF_IGNORE;
+ options.min_length = CO_MIN_LENGTH;
+ options.dig_credit = CO_DIG_CREDIT;
+ options.up_credit = CO_UP_CREDIT;
+ options.low_credit = CO_LOW_CREDIT;
+ options.oth_credit = CO_OTH_CREDIT;
+ options.use_authtok = CO_USE_AUTHTOK;
+ memset(options.prompt_type, 0, BUFSIZ);
- retry_times = 1;
- memset(prompt_type,0,sizeof(prompt_type));
- ctrl = _pam_parse(argc, argv);
+ ctrl = _pam_parse(&options, argc, argv);
D(("called."));
- if (!prompt_type[0])
- strcpy(prompt_type,"UNIX");
+ if (!options.prompt_type[0])
+ strcpy(options.prompt_type,"UNIX");
if (flags & PAM_PRELIM_CHECK) {
/* Check for passwd dictionary */
@@ -421,7 +506,6 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
} else if (flags & PAM_UPDATE_AUTHTOK) {
int retval;
char *token1, *token2, *oldtoken;
- const char *item;
struct pam_message msg[1],*pmsg[1];
struct pam_response *resp;
const char *cracklib_dictpath = CRACKLIB_DICTPATH;
@@ -443,7 +527,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
*/
token1 = token2 = NULL;
- if (!retry_times) {
+ if (!options.retry_times) {
D(("returning %s because maxtries reached",
pam_strerror(pamh, retval)));
return retval;
@@ -457,33 +541,51 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
* set PAM_AUTHTOK and return
*/
- /* Prepare to ask the user for the first time */
- memset(prompt,0,sizeof(prompt));
- sprintf(prompt,PROMPT1,prompt_type);
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
- resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token1 = x_strdup(resp[0].resp);
- if (token1 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 1");
- retval = PAM_AUTHTOK_RECOVER_ERR;
+ if (options.use_authtok == 1) {
+ const char *item = NULL;
+
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **) &item);
+ if (retval != PAM_SUCCESS) {
+ /* very strange. */
+ _pam_log(LOG_ALERT
+ ,"pam_get_item returned error to pam_cracklib"
+ );
+ } else if (item != NULL) { /* we have a password! */
+ token1 = x_strdup(item);
+ item = NULL;
+ } else {
+ retval = PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ }
+
+ } else {
+ /* Prepare to ask the user for the first time */
+ memset(prompt,0,sizeof(prompt));
+ sprintf(prompt,PROMPT1,options.prompt_type);
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = prompt;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+ if (resp != NULL) {
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token1 = x_strdup(resp[0].resp);
+ if (token1 == NULL) {
+ _pam_log(LOG_NOTICE,
+ "could not recover authentication token 1");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ }
}
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ */
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS) ?
+ PAM_AUTHTOK_RECOVER_ERR:retval ;
}
- /*
- * tidy up the conversation (resp_retcode) is ignored
- */
- _pam_drop_reply(resp, 1);
- } else {
- retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
- }
+ }
if (retval != PAM_SUCCESS) {
if (ctrl && PAM_DEBUG_ARG)
@@ -512,13 +614,14 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* check it for strength too... */
D(("for strength"));
if (oldtoken) {
- retval = _pam_unix_approve_pass(pamh,ctrl,
+ retval = _pam_unix_approve_pass(pamh,ctrl,&options,
oldtoken,token1);
- if (retval != PAM_SUCCESS)
+ if (retval != PAM_SUCCESS) {
if (getuid() || (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
retval = PAM_AUTHTOK_ERR;
else
retval = PAM_SUCCESS;
+ }
}
}
}
@@ -534,77 +637,81 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
/* Now we have a good passwd. Ask for it once again */
-
- bzero(prompt,sizeof(prompt));
- sprintf(prompt,PROMPT2,prompt_type);
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = prompt;
-
- resp = NULL;
- retval = converse(pamh, ctrl, 1, pmsg, &resp);
- if (resp != NULL) {
- /* interpret the response */
- if (retval == PAM_SUCCESS) { /* a good conversation */
- token2 = x_strdup(resp[0].resp);
- if (token2 == NULL) {
- _pam_log(LOG_NOTICE,
- "could not recover authentication token 2");
- retval = PAM_AUTHTOK_RECOVER_ERR;
+
+ if (options.use_authtok == 0) {
+ bzero(prompt,sizeof(prompt));
+ sprintf(prompt,PROMPT2,options.prompt_type);
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = prompt;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+ if (resp != NULL) {
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token2 = x_strdup(resp[0].resp);
+ if (token2 == NULL) {
+ _pam_log(LOG_NOTICE,
+ "could not recover authentication token 2");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ }
}
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ */
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS) ?
+ PAM_AUTHTOK_RECOVER_ERR:retval ;
}
- /*
- * tidy up the conversation (resp_retcode) is ignored
- */
- _pam_drop_reply(resp, 1);
- } else {
- retval = (retval == PAM_SUCCESS) ?
- PAM_AUTHTOK_RECOVER_ERR:retval ;
- }
- if (retval != PAM_SUCCESS) {
- if (ctrl && PAM_DEBUG_ARG)
- _pam_log(LOG_DEBUG
- ,"unable to obtain the password a second time");
- continue;
- }
+ if (retval != PAM_SUCCESS) {
+ if (ctrl && PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG
+ ,"unable to obtain the password a second time");
+ continue;
+ }
- /* Hopefully now token1 and token2 the same password ... */
- if (strcmp(token1,token2) != 0) {
- /* tell the user */
- make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS);
- token1 = _pam_delete(token1);
- token2 = _pam_delete(token2);
- pam_set_item(pamh, PAM_AUTHTOK, NULL);
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_NOTICE,"Password mistyped");
- retval = PAM_AUTHTOK_RECOVER_ERR;
- continue;
- }
+ /* Hopefully now token1 and token2 the same password ... */
+ if (strcmp(token1,token2) != 0) {
+ /* tell the user */
+ make_remark(pamh, ctrl, PAM_ERROR_MSG, MISTYPED_PASS);
+ token1 = _pam_delete(token1);
+ token2 = _pam_delete(token2);
+ pam_set_item(pamh, PAM_AUTHTOK, NULL);
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_NOTICE,"Password mistyped");
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ continue;
+ }
- /* Yes, the password was typed correct twice
- * we store this password as an item
- */
+ /* Yes, the password was typed correct twice
+ * we store this password as an item
+ */
- retval = pam_set_item(pamh, PAM_AUTHTOK, token1);
- /* clean it up */
- token1 = _pam_delete(token1);
- token2 = _pam_delete(token2);
- if (
- (retval != PAM_SUCCESS) ||
- (
- (
- retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item)
- ) != PAM_SUCCESS
- )
- ) {
- _pam_log(LOG_CRIT, "error manipulating password");
- continue;
+ {
+ const char *item = NULL;
+
+ retval = pam_set_item(pamh, PAM_AUTHTOK, token1);
+
+ /* clean up */
+ token1 = _pam_delete(token1);
+ token2 = _pam_delete(token2);
+
+ if ( (retval != PAM_SUCCESS) ||
+ ((retval = pam_get_item(pamh, PAM_AUTHTOK,
+ (const void **)&item)
+ ) != PAM_SUCCESS) ) {
+ _pam_log(LOG_CRIT, "error manipulating password");
+ continue;
+ }
+ item = NULL; /* break link to password */
+ return PAM_SUCCESS;
+ }
}
- item = NULL; /* break link to password */
- return PAM_SUCCESS;
- } while (retry_times--);
+ } while (options.retry_times--);
} else {
if (ctrl & PAM_DEBUG_ARG)
diff --git a/contrib/libpam/modules/pam_deny/Makefile b/contrib/libpam/modules/pam_deny/Makefile
index 02506cb38122..2fdd6e1111a5 100644
--- a/contrib/libpam/modules/pam_deny/Makefile
+++ b/contrib/libpam/modules/pam_deny/Makefile
@@ -1,125 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:43:41 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:43:41 morgan
-# full-source-tree and fakeroot
-#
-# Revision 1.6 1997/02/15 19:04:27 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:11:48 morgan
-# crossplatform support
-#
-# Revision 1.4 1996/09/05 06:50:12 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:48:38 morgan
-# make dynamic and static dirs
-#
-# Revision 1.2 1996/05/26 04:00:16 morgan
-# changes for automated static/dynamic modules
-#
-# Revision 1.1 1996/03/16 17:47:36 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-#
+include ../../Make.Rules
TITLE=pam_deny
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_deny/README b/contrib/libpam/modules/pam_deny/README
index 4f7f6de664fe..2eb96d4e35d1 100644
--- a/contrib/libpam/modules/pam_deny/README
+++ b/contrib/libpam/modules/pam_deny/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/03/16 18:11:12 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:33 agmorgan Exp $
#
this module always fails, it ignores all options.
diff --git a/contrib/libpam/modules/pam_deny/pam_deny.c b/contrib/libpam/modules/pam_deny/pam_deny.c
index 76ba24d3fd90..8be1a8a87f55 100644
--- a/contrib/libpam/modules/pam_deny/pam_deny.c
+++ b/contrib/libpam/modules/pam_deny/pam_deny.c
@@ -1,23 +1,10 @@
/* pam_permit module */
/*
- * $Id: pam_deny.c,v 1.4 1997/02/15 19:05:15 morgan Exp $
+ * $Id: pam_deny.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
*
- * $Log: pam_deny.c,v $
- * Revision 1.4 1997/02/15 19:05:15 morgan
- * fixed email
- *
- * Revision 1.3 1996/06/02 08:06:19 morgan
- * changes for new static protocol
- *
- * Revision 1.2 1996/05/26 04:01:12 morgan
- * added static support
- *
- * Revision 1.1 1996/03/16 17:47:36 morgan
- * Initial revision
- *
*/
/*
diff --git a/contrib/libpam/modules/pam_env/Makefile b/contrib/libpam/modules/pam_env/Makefile
index df363bc9536b..189f1ee3fe6a 100644
--- a/contrib/libpam/modules/pam_env/Makefile
+++ b/contrib/libpam/modules/pam_env/Makefile
@@ -1,107 +1,22 @@
#
-# $Id: Makefile,v 1.1 1997/04/05 06:42:35 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.1 1997/04/05 06:42:35 morgan
-# Initial revision
-#
-# Revision 1.1 1997/01/04 20:32:52 morgan
-# Initial revision
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-# Adaptations by Dave Kinclea and Cristian Gafton
-#
-
-TITLE=pam_env
-
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/pam_env.conf
-export CONFILE
-
-#ifeq ($(HAVE_PWDBLIB),yes)
-#CFLAGS += -DWANT_PWDB
-#EXTRALIB = -lpwdb
-#endif
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+include ../../Make.Rules
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(EXTRALIB)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
+TITLE=pam_env
+LOCAL_CONFILE=./pam_env.conf-example
+INSTALLED_CONFILE=$(SCONFIGD)/pam_env.conf
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
+CFLAGS += $(DEFS)
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_env/README b/contrib/libpam/modules/pam_env/README
index d6e959cdbee5..5053618a7835 100644
--- a/contrib/libpam/modules/pam_env/README
+++ b/contrib/libpam/modules/pam_env/README
@@ -1,6 +1,6 @@
-# $Date: 1997/04/05 06:42:35 $
-# $Author: morgan $
-# $Id: README,v 1.1 1997/04/05 06:42:35 morgan Exp $
+# $Date: 2000/06/20 22:11:33 $
+# $Author: agmorgan $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:33 agmorgan Exp $
#
# This is the configuration file for pam_env, a PAM module to load in
# a configurable list of environment variables for a
diff --git a/contrib/libpam/modules/pam_env/pam_env.c b/contrib/libpam/modules/pam_env/pam_env.c
index bd0879c52283..5f5aa815e6be 100644
--- a/contrib/libpam/modules/pam_env/pam_env.c
+++ b/contrib/libpam/modules/pam_env/pam_env.c
@@ -1,59 +1,21 @@
/* pam_mail module */
/*
- * $Id: pam_env.c,v 1.1 1997/04/05 06:42:35 morgan Exp morgan $
+ * $Id: pam_env.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* Written by Dave Kinchlea <kinch@kinch.ark.com> 1997/01/31
* Inspired by Andrew Morgan <morgan@parc.power.net, who also supplied the
* template for this file (via pam_mail)
- *
- * $Log: pam_env.c,v $
- * Revision 1.1 1997/04/05 06:42:35 morgan
- * Initial revision
- *
- * Revision 0.6 1997/02/04 17:58:27 kinch
- * Debugging code cleaned up, lots added (whereever _log_err called) some removed
- *
- * Revision 0.5 1997/02/04 17:20:30 kinch
- * Changed default config file
- * Removed bogus message in pam_sm_authenticate()
- * Added back support in pam_sm_session(), this could conceivably be used
- * both as an auth_setcred and a session module
- *
- * Revision 0.4 1997/02/04 07:34:15 kinch
- * Fixed dealing with escaped '$' and '@' characters
- * This is now an pam_sm_setcred module to work closer to the RFC model
- * though this whole thing seems to have little to do with Authentication
- *
- * Revision 0.3 1997/02/04 04:53:15 kinch
- * Removed bogus space in PAM_ENV_SILENT
- * Removed line that added a space when allowing for escaped newlines, that
- * is not what we want at all, if we want a space, we can add one.
- * Changed a PAM_ABORT to PAM_BUF_ERR for a malloc failure
- * Changed bogus PAM_RUSER to PAM_RHOST
- *
- * Revision 0.2 1997/02/03 23:31:26 kinch
- * Lots of D(()) debugging code added, probably too much actually.
- * This now seems to work for all cases I can think of
- * Lots of little code changes but nothing major and no function
- * interface changes, largest change has to do with adding the
- * logic to get &quote hack to make it through all the code. Probably
- * ought to have done this with a global flag for each of defval and
- * override - it would have been cleaner.
- *
- * Revision 0.1 1997/02/03 01:39:06 kinch
- * Initial code, it compiles cleanly but has not been tested at all.
- *
*/
#ifndef DEFAULT_CONF_FILE
#define DEFAULT_CONF_FILE "/etc/security/pam_env.conf"
#endif
-#ifdef linux
-#define _GNU_SOURCE
-#include <features.h>
-#endif
+#define DEFAULT_ETC_ENVFILE "/etc/environment"
+#define DEFAULT_READ_ENVFILE 1
+
+#include <security/_pam_aconf.h>
#include <ctype.h>
#include <errno.h>
@@ -67,10 +29,6 @@
#include <sys/types.h>
#include <unistd.h>
-#ifdef WANT_PWDB
-#include <pwdb/pwdb_public.h>
-#endif
-
/*
* here, we make a definition for the externally accessible function
* in this file (this definition is required for static a module
@@ -132,11 +90,13 @@ static void _log_err(int err, const char *format, ...)
/* argument parsing */
-#define PAM_DEBUG_ARG 01
-#define PAM_NEW_CONF_FILE 02
-#define PAM_ENV_SILENT 04
+#define PAM_DEBUG_ARG 0x01
+#define PAM_NEW_CONF_FILE 0x02
+#define PAM_ENV_SILENT 0x04
+#define PAM_NEW_ENV_FILE 0x10
-static int _pam_parse(int flags, int argc, const char **argv, char **conffile)
+static int _pam_parse(int flags, int argc, const char **argv, char **conffile,
+ char **envfile, int *readenv)
{
int ctrl=0;
@@ -157,9 +117,19 @@ static int _pam_parse(int flags, int argc, const char **argv, char **conffile)
_log_err(LOG_CRIT,
"Configuration file specification missing argument - ignored");
}
- } else {
+ } else if (!strncmp(*argv,"envfile=",8)) {
+ *envfile = x_strdup(8+*argv);
+ if (*envfile != NULL) {
+ D(("new Env File: %s", *envfile));
+ ctrl |= PAM_NEW_ENV_FILE;
+ } else {
+ _log_err(LOG_CRIT,
+ "Env file specification missing argument - ignored");
+ }
+ } else if (!strncmp(*argv,"readenv=",8))
+ *readenv = atoi(8+*argv);
+ else
_log_err(LOG_ERR,"pam_parse: unknown option; %s",*argv);
- }
}
return ctrl;
@@ -192,7 +162,7 @@ static int _parse_config_file(pam_handle_t *pamh, int ctrl, char **conffile)
if ((conf = fopen(file,"r")) == NULL) {
_log_err(LOG_ERR, "Unable to open config file: %s",
strerror(errno));
- return PAM_ABORT;
+ return PAM_IGNORE;
}
/* _pam_assemble_line will provide a complete line from the config file, with all
@@ -230,6 +200,88 @@ static int _parse_config_file(pam_handle_t *pamh, int ctrl, char **conffile)
return (retval<0?PAM_ABORT:PAM_SUCCESS);
}
+static int _parse_env_file(pam_handle_t *pamh, int ctrl, char **env_file)
+{
+ int retval=PAM_SUCCESS, i, t;
+ const char *file;
+ char buffer[BUF_SIZE], *key, *mark;
+ FILE *conf;
+
+ if (ctrl & PAM_NEW_ENV_FILE)
+ file = *env_file;
+ else
+ file = DEFAULT_ETC_ENVFILE;
+
+ D(("Env file name is: %s", file));
+
+ if ((conf = fopen(file,"r")) == NULL) {
+ D(("Unable to open env file: %s", strerror(errno)));
+ return PAM_ABORT;
+ }
+
+ while (_assemble_line(conf, buffer, BUF_SIZE) > 0) {
+ D(("Read line: %s", buffer));
+ key = buffer;
+
+ /* skip leading white space */
+ key += strspn(key, " \n\t");
+
+ /* skip blanks lines and comments */
+ if (!key || key[0] == '#')
+ continue;
+
+ /* skip over "export " if present so we can be compat with
+ bash type declerations */
+ if (strncmp(key, "export ", (size_t) 7) == 0)
+ key += 7;
+
+ /* now find the end of value */
+ mark = key;
+ while(mark[0] != '\n' && mark[0] != '#' && mark[0] != '\0')
+ mark++;
+ if (mark[0] != '\0')
+ mark[0] = '\0';
+
+ /*
+ * sanity check, the key must be alpha-numeric
+ */
+
+ for ( i = 0 ; key[i] != '=' && key[i] != '\0' ; i++ )
+ if (!isalnum(key[i]) && key[i] != '_') {
+ D(("key is not alpha numeric - '%s', ignoring", key));
+ continue;
+ }
+
+ /* now we try to be smart about quotes around the value,
+ but not too smart, we can't get all fancy with escaped
+ values like bash */
+ if (key[i] == '=' && (key[++i] == '\"' || key[i] == '\'')) {
+ for ( t = i+1 ; key[t] != '\0' ; t++)
+ if (key[t] != '\"' && key[t] != '\'')
+ key[i++] = key[t];
+ else if (key[t+1] != '\0')
+ key[i++] = key[t];
+ key[i] = '\0';
+ }
+
+ /* set the env var, if it fails, we break out of the loop */
+ retval = pam_putenv(pamh, key);
+ if (retval != PAM_SUCCESS) {
+ D(("error setting env \"%s\"", key));
+ break;
+ }
+ }
+
+ (void) fclose(conf);
+
+ /* tidy up */
+ _pam_overwrite(*env_file);
+ _pam_drop(*env_file);
+ file = NULL;
+ D(("Exit."));
+ return (retval<0?PAM_IGNORE:PAM_SUCCESS);
+}
+
/*
* This is where we read a line of the PAM config file. The line may be
* preceeded by lines of comments and also extended with "\\\n"
@@ -536,7 +588,7 @@ static int _expand_arg(pam_handle_t *pamh, char **value)
_log_err(LOG_ERR, "Unterminated expandable variable: <%s>", orig-2);
return PAM_ABORT;
}
- strcpy(tmpval, orig);
+ strncpy(tmpval, orig, (size_t) BUF_SIZE);
orig=ptr;
/*
* so, we know we need to expand tmpval, it is either
@@ -696,18 +748,21 @@ PAM_EXTERN
int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
const char **argv)
{
- int retval, ctrl;
- char *conf_file=NULL;
-
+ int retval, ctrl, readenv=DEFAULT_READ_ENVFILE;
+ char *conf_file=NULL, *env_file=NULL;
+
/*
* this module sets environment variables read in from a file
*/
D(("Called."));
- ctrl = _pam_parse(flags, argc, argv, &conf_file);
-
+ ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv);
+
retval = _parse_config_file(pamh, ctrl, &conf_file);
-
+
+ if(readenv)
+ _parse_env_file(pamh, ctrl, &env_file);
+
/* indicate success or failure */
D(("Exit."));
@@ -726,18 +781,21 @@ PAM_EXTERN
int pam_sm_open_session(pam_handle_t *pamh,int flags,int argc
,const char **argv)
{
- int retval, ctrl;
- char *conf_file=NULL;
+ int retval, ctrl, readenv=DEFAULT_READ_ENVFILE;
+ char *conf_file=NULL, *env_file=NULL;
/*
* this module sets environment variables read in from a file
*/
D(("Called."));
- ctrl = _pam_parse(flags, argc, argv, &conf_file);
+ ctrl = _pam_parse(flags, argc, argv, &conf_file, &env_file, &readenv);
retval = _parse_config_file(pamh, ctrl, &conf_file);
+ if(readenv)
+ _parse_env_file(pamh, ctrl, &env_file);
+
/* indicate success or failure */
D(("Exit."));
diff --git a/contrib/libpam/modules/pam_env/pam_env.conf-example b/contrib/libpam/modules/pam_env/pam_env.conf-example
index 388e8b6b16d4..89637083be4e 100644
--- a/contrib/libpam/modules/pam_env/pam_env.conf-example
+++ b/contrib/libpam/modules/pam_env/pam_env.conf-example
@@ -1,6 +1,6 @@
-# $Date: 1997/04/05 06:42:35 $
-# $Author: morgan $
-# $Id: pam_env.conf-example,v 1.1 1997/04/05 06:42:35 morgan Exp $
+# $Date: 2000/06/20 22:11:35 $
+# $Author: agmorgan $
+# $Id: pam_env.conf-example,v 1.1.1.1 2000/06/20 22:11:35 agmorgan Exp $
#
# This is the configuration file for pam_env, a PAM module to load in
# a configurable list of environment variables for a
diff --git a/contrib/libpam/modules/pam_filter/Makefile b/contrib/libpam/modules/pam_filter/Makefile
index dbd6452ab285..1126aff9b301 100644
--- a/contrib/libpam/modules/pam_filter/Makefile
+++ b/contrib/libpam/modules/pam_filter/Makefile
@@ -1,24 +1,11 @@
#
-# $Id: Makefile,v 1.10 1997/04/05 06:41:09 morgan Exp $
+# $Id: Makefile,v 1.3 2000/12/21 06:06:34 vorlon Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.10 1997/04/05 06:41:09 morgan
-# fakeroot
-#
-# Revision 1.9 1997/02/15 18:58:48 morgan
-# fixed bash syntax
-#
-# Revision 1.8 1997/01/04 20:24:29 morgan
-# don't compile on solaris, make -> $(MAKE)
-#
-# Revision 1.7 1996/11/10 20:12:09 morgan
-# cross platform support
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
#
ifeq ($(OS),solaris)
@@ -27,12 +14,14 @@ include ../dont_makefile
else
+include ../../Make.Rules
+
TITLE=pam_filter
FILTERS=upperLOWER
FILTERSDIR=$(SUPLEMENTED)/pam_filter
export FILTERSDIR
-#
+CFLAGS += -Iinclude
LIBSRC = $(TITLE).c
LIBOBJ = $(TITLE).o
@@ -55,10 +44,6 @@ endif
####################### don't edit below #######################
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
#
# this is where we compile this module
#
@@ -66,6 +51,7 @@ dummy:
all: dirs $(LIBSHARED) $(LIBSTATIC) register filters
dirs:
+ if [ ! -r include/security ]; then ln -sf . include/security ; fi
ifdef DYNAMIC
$(MKDIR) ./dynamic
endif
@@ -104,6 +90,15 @@ $(LIBSTATIC): $(LIBOBJS)
$(LD) -r -o $@ $(LIBOBJS)
endif
+remove:
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ rm -f $(FAKEROOT)$(INCLUDED)/pam_filter.h
+ @for i in $(FILTERS) ; do \
+ if [ -d $$i ]; then \
+ $(MAKE) -C $$i remove ; \
+ fi ; \
+ done
+
install: all
@for i in $(FILTERS) ; do \
if [ -d $$i ]; then \
@@ -117,34 +112,15 @@ endif
$(MKDIR) $(FAKEROOT)$(INCLUDED)
$(INSTALL) -m 644 include/pam_filter.h $(FAKEROOT)$(INCLUDED)
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(INCLUDED)/pam_filter.h
- @for i in $(FILTERS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i remove ; \
- fi ; \
- done
-
-lclean:
- rm -f $(LIBSHARED) $(LIBOBJD) $(LIBOBJS) core *~
-
-clean: lclean
+clean:
@for i in $(FILTERS) ; do \
if [ -d $$i ]; then \
$(MAKE) -C $$i clean ; \
fi ; \
done
-
-extraclean: lclean
- @rm -f *.a *.o *.so *.bak
- for i in $(FILTERS) ; do \
- if [ -d $$i ]; then \
- $(MAKE) -C $$i extraclean ; \
- fi ; \
- done
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+ rm -f $(LIBSHARED) $(LIBOBJD) $(LIBOBJS) core *~
+ rm -f include/security
+ rm -fr dynamic static
+ rm -f *.a *.o *.so *.bak
endif
diff --git a/contrib/libpam/modules/pam_filter/README b/contrib/libpam/modules/pam_filter/README
index 9d46a56e5c9c..12c4aeb5175b 100644
--- a/contrib/libpam/modules/pam_filter/README
+++ b/contrib/libpam/modules/pam_filter/README
@@ -1,5 +1,5 @@
#
-# $Id: README,v 1.5 1996/12/01 02:53:08 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:35 agmorgan Exp $
#
# This describes the behavior of this module with respect to the
# /etc/pam.conf file.
diff --git a/contrib/libpam/modules/pam_filter/include/pam_filter.h b/contrib/libpam/modules/pam_filter/include/pam_filter.h
index 3eb2730e768b..69e3a3e298ab 100644
--- a/contrib/libpam/modules/pam_filter/include/pam_filter.h
+++ b/contrib/libpam/modules/pam_filter/include/pam_filter.h
@@ -1,8 +1,8 @@
/*
- * $Id: pam_filter.h,v 1.2 1997/02/15 19:09:09 morgan Exp $
+ * $Id: pam_filter.h,v 1.1.1.1 2000/06/20 22:11:36 agmorgan Exp $
*
* this file is associated with the Linux-PAM filter module.
- * it was written by Andrew G. Morgan <morgan@parc.power.net>
+ * it was written by Andrew G. Morgan <morgan@linux.kernel.org>
*
*/
diff --git a/contrib/libpam/modules/pam_filter/pam_filter.c b/contrib/libpam/modules/pam_filter/pam_filter.c
index fc3d1f2b53fc..3ab2d8670646 100644
--- a/contrib/libpam/modules/pam_filter/pam_filter.c
+++ b/contrib/libpam/modules/pam_filter/pam_filter.c
@@ -1,24 +1,12 @@
/*
- * $Id: pam_filter.c,v 1.9 1997/02/15 19:07:49 morgan Exp morgan $
- *
- * $Log: pam_filter.c,v $
- * Revision 1.9 1997/02/15 19:07:49 morgan
- * fixed email
- *
- * Revision 1.8 1996/11/10 20:59:23 morgan
- * gcc warning removed
- *
- * Revision 1.7 1996/07/08 00:01:17 morgan
- * set the PAM_TTY item now
- *
- * Revision 1.6 1996/06/02 08:08:19 morgan
- * completely re-written
- *
+ * $Id: pam_filter.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* written by Andrew Morgan <morgan@transmeta.com> with much help from
* Richard Stevens' UNIX Network Programming book.
*/
+#include <security/_pam_aconf.h>
+
#include <stdlib.h>
#include <syslog.h>
#include <unistd.h>
diff --git a/contrib/libpam/modules/pam_filter/upperLOWER/Makefile b/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
index 09b693bf6803..92da2479e0a8 100644
--- a/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
+++ b/contrib/libpam/modules/pam_filter/upperLOWER/Makefile
@@ -1,44 +1,28 @@
#
-# $Id: Makefile,v 1.5 1997/04/05 06:41:35 morgan Exp $
-#
-# $Log: Makefile,v $
-# Revision 1.5 1997/04/05 06:41:35 morgan
-# fakeroot
-#
-# Revision 1.4 1997/01/04 20:25:04 morgan
-# removed need for make
-#
-# Revision 1.3 1996/11/10 20:13:08 morgan
-# email address
-#
-# Revision 1.2 1996/11/10 20:12:24 morgan
-# cross platform support
-#
-# Revision 1.1 1996/06/02 08:17:02 morgan
-# Initial revision
-#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This directory contains a pam_filter filter executable
#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@transmeta.com> 1996/3/11
#
+include ../../../Make.Rules
+
TITLE=upperLOWER
#
+CFLAGS += -I../include
+
OBJS = $(TITLE).o
####################### don't edit below #######################
-dummy:
- @echo "**** This is not a top-level Makefile "
-
all: $(TITLE)
$(TITLE): $(OBJS)
$(CC) -o $(TITLE) $(OBJS)
- strip $(TITLE)
+ $(STRIP) $(TITLE)
install:
$(MKDIR) $(FAKEROOT)$(FILTERSDIR)
@@ -50,9 +34,6 @@ remove:
clean:
rm -f $(TITLE) $(OBJS) core *~
-extraclean: clean
- rm -f *.bak
-
.c.o:
$(CC) $(CFLAGS) -c $<
diff --git a/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c b/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
index b375c0794edf..6178c2797e2e 100644
--- a/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
+++ b/contrib/libpam/modules/pam_filter/upperLOWER/upperLOWER.c
@@ -1,17 +1,14 @@
/*
- * $Id: upperLOWER.c,v 1.1 1996/06/02 08:17:02 morgan Exp $
+ * $Id: upperLOWER.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
* This is a sample filter program, for use with pam_filter (a module
* provided with Linux-PAM). This filter simply transposes upper and
* lower case letters, it is intended for demonstration purposes and
* it serves no purpose other than to annoy the user...
- *
- * $Log: upperLOWER.c,v $
- * Revision 1.1 1996/06/02 08:17:02 morgan
- * Initial revision
- *
*/
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
#include <syslog.h>
#include <sys/time.h>
@@ -52,7 +49,9 @@ static void do_transpose(char *buffer,int len)
}
}
-int main(int argc, char **argv, char **envp)
+extern char **environ;
+
+int main(int argc, char **argv)
{
char buffer[BUFSIZ];
fd_set readers;
@@ -64,8 +63,8 @@ int main(int argc, char **argv, char **envp)
int i;
fprintf(stderr,"environment :[\r\n");
- for (i=0; envp[i]; ++i) {
- fprintf(stderr,"-> %s\r\n",envp[i]);
+ for (i=0; environ[i]; ++i) {
+ fprintf(stderr,"-> %s\r\n",environ[i]);
}
fprintf(stderr,"]: end\r\n");
}
diff --git a/contrib/libpam/modules/pam_ftp/Makefile b/contrib/libpam/modules/pam_ftp/Makefile
index b5355c68b55e..456161bfe597 100644
--- a/contrib/libpam/modules/pam_ftp/Makefile
+++ b/contrib/libpam/modules/pam_ftp/Makefile
@@ -1,96 +1,15 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:40:33 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:40:33 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1996/12/01 03:17:57 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/11/14
-#
-
-TITLE=pam_ftp
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-dummy:
+include ../../Make.Rules
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_ftp
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_ftp/README b/contrib/libpam/modules/pam_ftp/README
index 597f9120bd86..6d03330c10ed 100644
--- a/contrib/libpam/modules/pam_ftp/README
+++ b/contrib/libpam/modules/pam_ftp/README
@@ -1,20 +1,18 @@
-# $Id: README,v 1.1 1996/12/01 03:17:57 morgan Exp $
-#
+This is the README for pam_ftp
+------------------------------
-This module is an authentication module that does not authenticate.
-Instead it always returns PAM_IGNORE, indicating that it does not want
-to affect the authentication process.
-
-Its purpose is to log a message to the syslog indicating the
-pam_item's available at the time it was invoked. It is a diagnostic
-tool.
+This module is an authentication module that does simple ftp
+authentication.
Recognized arguments:
- none
-
-module services provided:
+ "debug" print debug messages
+ "users=" comma separated list of users which
+ could login only with email adress
+ "ignore" allow invalid email adresses
- auth _authetication and _setcred (blank)
+Options for:
+auth: for authentication it provides pam_authenticate() and
+ pam_setcred() hooks.
-Andrew Morgan
+Thorsten Kukuk <kukuk@suse.de>, 17. June 1999
diff --git a/contrib/libpam/modules/pam_ftp/pam_ftp.c b/contrib/libpam/modules/pam_ftp/pam_ftp.c
index ca2d41545e94..3fcbcec8cd54 100644
--- a/contrib/libpam/modules/pam_ftp/pam_ftp.c
+++ b/contrib/libpam/modules/pam_ftp/pam_ftp.c
@@ -1,17 +1,9 @@
/* pam_ftp module */
/*
- * $Id: pam_ftp.c,v 1.2 1997/02/15 16:23:59 morgan Exp morgan $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_ftp.c,v $
- * Revision 1.2 1997/02/15 16:23:59 morgan
- * fixed logging to avoid a fixed buffer size
- *
- * Revision 1.1 1996/12/01 03:17:57 morgan
- * Initial revision
+ * $Id: pam_ftp.c,v 1.2 2000/11/19 23:54:03 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*
*/
@@ -22,10 +14,7 @@
/* the following is a password that "can't be correct" */
#define BLOCK_PASSWORD "\177BAD PASSWPRD\177"
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -76,7 +65,7 @@ static int converse(pam_handle_t *pamh, int nargs
D(("returned from application's conversation function\n"));
- if (retval != PAM_SUCCESS) {
+ if ((retval != PAM_SUCCESS) && (retval != PAM_CONV_AGAIN)) {
_pam_log(LOG_DEBUG, "conversation failure [%s]"
, pam_strerror(pamh, retval));
}
@@ -211,24 +200,33 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
char *prompt=NULL;
int i=0;
- mesg[i] = &msg[i];
- msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
- if (anon) {
- prompt = malloc(sizeof(PLEASE_ENTER_PASSWORD + strlen(user)));
- sprintf(prompt, PLEASE_ENTER_PASSWORD, user);
- msg[i].msg = prompt;
+ if (!anon) {
+ prompt = malloc(strlen(PLEASE_ENTER_PASSWORD) + strlen(user));
+ if (prompt == NULL) {
+ D(("out of memory!?"));
+ return PAM_BUF_ERR;
+ } else {
+ sprintf(prompt, PLEASE_ENTER_PASSWORD, user);
+ msg[i].msg = prompt;
+ }
} else {
msg[i].msg = GUEST_LOGIN_PROMPT;
}
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ mesg[i] = &msg[i];
+
retval = converse(pamh, ++i, mesg, &resp);
- _pam_overwrite(prompt);
- _pam_drop(prompt);
+ if (prompt) {
+ _pam_overwrite(prompt);
+ _pam_drop(prompt);
+ }
if (retval != PAM_SUCCESS) {
if (resp != NULL)
_pam_drop_reply(resp,i);
- return PAM_AUTHINFO_UNAVAIL;
+ return ((retval == PAM_CONV_AGAIN)
+ ? PAM_INCOMPLETE:PAM_AUTHINFO_UNAVAIL);
}
if (anon) {
@@ -238,11 +236,15 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
token = strtok(resp->resp, "@");
retval = pam_set_item(pamh, PAM_RUSER, token);
- if (token && retval != PAM_SUCCESS) {
+ if ((token) && (retval == PAM_SUCCESS)) {
token = strtok(NULL, "@");
retval = pam_set_item(pamh, PAM_RHOST, token);
}
}
+
+ /* we are happy to grant annonymous access to the user */
+ retval = PAM_SUCCESS;
+
} else {
/*
* we have a password so set AUTHTOK
diff --git a/contrib/libpam/modules/pam_group/Makefile b/contrib/libpam/modules/pam_group/Makefile
index 5db53ccf1133..afa888803315 100644
--- a/contrib/libpam/modules/pam_group/Makefile
+++ b/contrib/libpam/modules/pam_group/Makefile
@@ -1,114 +1,21 @@
-#
-# $Id: Makefile,v 1.6 1997/04/05 06:39:56 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.6 1997/04/05 06:39:56 morgan
-# fakeroot
-#
-# Revision 1.5 1997/01/04 20:28:47 morgan
-# compile with and without libpwdb
-#
-# Revision 1.4 1996/11/10 20:13:18 morgan
-# cross platform support
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/6/11
-#
-
-TITLE=pam_group
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/group.conf
-export CONFILE
-
-#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
-ifndef STATIC
-ifeq ($(HAVE_PWDBLIB),yes)
- DEFS+=-DWANT_PWDB
- ELIBS=-lpwdb
-endif
-endif
+TITLE=pam_group
+LOCAL_CONFILE=./group.conf
+INSTALLED_CONFILE=$(SCONFIGD)/group.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(ELIBS)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(ELIBS)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_group/group.conf b/contrib/libpam/modules/pam_group/group.conf
index bdd76adbe68f..e721b9907eea 100644
--- a/contrib/libpam/modules/pam_group/group.conf
+++ b/contrib/libpam/modules/pam_group/group.conf
@@ -10,7 +10,7 @@
# *** NOT inherently secure. If a user can create an executable that
# *** is setgid a group that they are infrequently given membership
# *** of, they can basically obtain group membership any time they
-# *** like. Example: games are alowed between the hours of 6pm and 6am
+# *** like. Example: games are allowed between the hours of 6pm and 6am
# *** user joe logs in at 7pm writes a small C-program toplay.c that
# *** invokes their favorite shell, compiles it and does
# *** "chgrp games toplay; chmod g+s toplay". They are basically able
diff --git a/contrib/libpam/modules/pam_group/pam_group.c b/contrib/libpam/modules/pam_group/pam_group.c
index 9e2cf885e9cf..2d04119ad88a 100644
--- a/contrib/libpam/modules/pam_group/pam_group.c
+++ b/contrib/libpam/modules/pam_group/pam_group.c
@@ -1,32 +1,17 @@
/* pam_group module */
/*
- * $Id: pam_group.c,v 1.7 1997/02/15 17:31:48 morgan Exp morgan $
+ * $Id: pam_group.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/7/6
- *
- * $Log: pam_group.c,v $
- * Revision 1.7 1997/02/15 17:31:48 morgan
- * time parsing more robust
- *
- * Revision 1.6 1997/01/04 21:57:49 morgan
- * fixed warning about setgroups not being defined
- *
- * Revision 1.5 1997/01/04 20:26:49 morgan
- * can be compiled with and without libpwdb. fixed buffer underwriting
- * pays attention to PAM_CRED flags(!)
- *
- * Revision 1.4 1996/12/01 02:54:37 morgan
- * mostly debugging now uses D(())
- *
- * Revision 1.3 1996/11/10 21:01:22 morgan
- * compatability and pam_get_user changes
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/7/6
*/
const static char rcsid[] =
-"$Id: pam_group.c,v 1.7 1997/02/15 17:31:48 morgan Exp morgan $;\n"
+"$Id: pam_group.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $;\n"
"Version 0.5 for Linux-PAM\n"
-"Copyright (c) Andrew G. Morgan 1996 <morgan@parc.power.net>\n";
+"Copyright (c) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
+
+#define _BSD_SOURCE
#include <sys/file.h>
#include <stdio.h>
@@ -38,17 +23,16 @@ const static char rcsid[] =
#include <syslog.h>
#include <string.h>
-#define __USE_BSD
#include <grp.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
-#ifdef WANT_PWDB
-#include <pwdb/pwdb_public.h>
+#ifdef DEFAULT_CONF_FILE
+# define PAM_GROUP_CONF DEFAULT_CONF_FILE /* from external define */
+#else
+# define PAM_GROUP_CONF "/etc/security/group.conf"
#endif
-
-#define PAM_GROUP_CONF CONFILE /* from external define */
#define PAM_GROUP_BUFLEN 1000
#define FIELD_SEPARATOR ';' /* this is new as of .02 */
@@ -137,6 +121,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
_log_err("error reading " PAM_GROUP_CONF);
return -1;
} else if (!i) {
+ close(fd);
fd = -1; /* end of file reached */
} else
*to += i;
@@ -180,6 +165,8 @@ static int read_field(int fd, char **buf, int *from, int *to)
if ((*buf)[i+1] == '\n') {
shift_bytes(i + *buf, 2, *to - (i+2));
*to -= 2;
+ } else {
+ ++i; /* we don't escape non-newline characters */
}
break;
case '!':
@@ -260,7 +247,7 @@ static int logic_member(const char *string, int *at)
default:
if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
- || c == '-' || c == '.') {
+ || c == '-' || c == '.' || c == '/') {
token = 1;
} else if (token) {
--to;
diff --git a/contrib/libpam/modules/pam_issue/Makefile b/contrib/libpam/modules/pam_issue/Makefile
new file mode 100644
index 000000000000..1bd2be217db5
--- /dev/null
+++ b/contrib/libpam/modules/pam_issue/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_issue
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_issue/pam_issue.c b/contrib/libpam/modules/pam_issue/pam_issue.c
new file mode 100644
index 000000000000..2cb54bec77d6
--- /dev/null
+++ b/contrib/libpam/modules/pam_issue/pam_issue.c
@@ -0,0 +1,266 @@
+/* pam_issue module - a simple /etc/issue parser to set PAM_USER_PROMPT
+ *
+ * Copyright 1999 by Ben Collins <bcollins@debian.org>
+ *
+ * Needs to be called before any other auth modules so we can setup the
+ * user prompt before it's first used. Allows one argument option, which
+ * is the full path to a file to be used for issue (uses /etc/issue as a
+ * default) such as "issue=/etc/issue.telnet".
+ *
+ * We can also parse escapes within the the issue file (enabled by
+ * default, but can be disabled with the "noesc" option). It's the exact
+ * same parsing as util-linux's agetty program performs.
+ *
+ * Released under the GNU LGPL version 2 or later
+ */
+
+#define _GNU_SOURCE
+#define _BSD_SOURCE
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/utsname.h>
+#include <utmp.h>
+#include <malloc.h>
+
+#include <security/_pam_macros.h>
+
+#define PAM_SM_AUTH
+
+#include <security/pam_modules.h>
+
+static int _user_prompt_set = 0;
+
+char *do_prompt (FILE *);
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval = PAM_SUCCESS;
+ FILE *fd;
+ int parse_esc = 1;
+ char *prompt_tmp = NULL, *cur_prompt = NULL;
+ struct stat st;
+ char *issue_file = NULL;
+
+ /* If we've already set the prompt, don't set it again */
+ if(_user_prompt_set)
+ return PAM_IGNORE;
+ else
+ /* we set this here so if we fail below, we wont get further
+ than this next time around (only one real failure) */
+ _user_prompt_set = 1;
+
+ for ( ; argc-- > 0 ; ++argv ) {
+ if (!strncmp(*argv,"issue=",6)) {
+ issue_file = (char *) strdup(6+*argv);
+ if (issue_file != NULL) {
+ D(("set issue_file to: %s", issue_file));
+ } else {
+ D(("failed to strdup issue_file - ignored"));
+ return PAM_IGNORE;
+ }
+ } else if (!strcmp(*argv,"noesc")) {
+ parse_esc = 0;
+ D(("turning off escape parsing by request"));
+ } else
+ D(("unknown option passed: %s", *argv));
+ }
+
+ if (issue_file == NULL)
+ issue_file = strdup("/etc/issue");
+
+ if ((fd = fopen(issue_file, "r")) != NULL) {
+ int tot_size = 0;
+
+ if (stat(issue_file, &st) < 0)
+ return PAM_IGNORE;
+
+ retval = pam_get_item(pamh, PAM_USER_PROMPT, (const void **) &cur_prompt);
+ if (retval != PAM_SUCCESS)
+ return PAM_IGNORE;
+
+ /* first read in the issue file */
+
+ if (parse_esc)
+ prompt_tmp = do_prompt(fd);
+ else {
+ int count = 0;
+ prompt_tmp = malloc(st.st_size + 1);
+ if (prompt_tmp == NULL) return PAM_IGNORE;
+ memset (prompt_tmp, '\0', st.st_size + 1);
+ count = fread(prompt_tmp, sizeof(char *), st.st_size, fd);
+ prompt_tmp[st.st_size] = '\0';
+ }
+
+ fclose(fd);
+
+ tot_size = strlen(prompt_tmp) + strlen(cur_prompt) + 1;
+
+ /*
+ * alloc some extra space for the original prompt
+ * and postpend it to the buffer
+ */
+ prompt_tmp = realloc(prompt_tmp, tot_size);
+ strcpy(prompt_tmp+strlen(prompt_tmp), cur_prompt);
+
+ prompt_tmp[tot_size] = '\0';
+
+ retval = pam_set_item(pamh, PAM_USER_PROMPT, (const char *) prompt_tmp);
+
+ free(issue_file);
+ free(prompt_tmp);
+ } else {
+ D(("could not open issue_file: %s", issue_file));
+ return PAM_IGNORE;
+ }
+
+ return retval;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+char *do_prompt(FILE *fd)
+{
+ int c, size = 1024;
+ char *issue = (char *)malloc(size);
+ char buf[1024];
+ struct utsname uts;
+
+ if (issue == NULL || fd == NULL)
+ return NULL;
+
+ issue[0] = '\0'; /* zero this, for strcat to work on first buf */
+ (void) uname(&uts);
+
+ while ((c = getc(fd)) != EOF) {
+ if (c == '\\') {
+ c = getc(fd);
+ switch (c) {
+ case 's':
+ snprintf (buf, 1024, "%s", uts.sysname);
+ break;
+ case 'n':
+ snprintf (buf, 1024, "%s", uts.nodename);
+ break;
+ case 'r':
+ snprintf (buf, 1024, "%s", uts.release);
+ break;
+ case 'v':
+ snprintf (buf, 1024, "%s", uts.version);
+ break;
+ case 'm':
+ snprintf (buf, 1024, "%s", uts.machine);
+ break;
+ case 'o':
+ {
+ char domainname[256];
+
+ getdomainname(domainname, sizeof(domainname));
+ domainname[sizeof(domainname)-1] = '\0';
+ snprintf (buf, 1024, "%s", domainname);
+ }
+ break;
+
+ case 'd':
+ case 't':
+ {
+ const char *weekday[] = {
+ "Sun", "Mon", "Tue", "Wed", "Thu",
+ "Fri", "Sat" };
+ const char *month[] = {
+ "Jan", "Feb", "Mar", "Apr", "May",
+ "Jun", "Jul", "Aug", "Sep", "Oct",
+ "Nov", "Dec" };
+ time_t now;
+ struct tm *tm;
+
+ (void) time (&now);
+ tm = localtime(&now);
+
+ if (c == 'd')
+ snprintf (buf, 1024, "%s %s %d %d",
+ weekday[tm->tm_wday], month[tm->tm_mon],
+ tm->tm_mday,
+ tm->tm_year + 1900);
+ else
+ snprintf (buf, 1024, "%02d:%02d:%02d",
+ tm->tm_hour, tm->tm_min, tm->tm_sec);
+ }
+ break;
+ case 'l':
+ {
+ char *ttyn = ttyname(1);
+ if (!strncmp(ttyn, "/dev/", 5))
+ ttyn += 5;
+ snprintf (buf, 1024, "%s", ttyn);
+ }
+ break;
+ case 'u':
+ case 'U':
+ {
+ int users = 0;
+ struct utmp *ut;
+ setutent();
+ while ((ut = getutent()))
+ if (ut->ut_type == USER_PROCESS)
+ users++;
+ endutent();
+ printf ("%d ", users);
+ if (c == 'U')
+ snprintf (buf, 1024, "%s", (users == 1) ?
+ " user" : " users");
+ break;
+ }
+ default:
+ buf[0] = c; buf[1] = '\0';
+ }
+ if ((strlen(issue) + strlen(buf)) < size + 1) {
+ size += strlen(buf) + 1;
+ issue = (char *) realloc (issue, size);
+ }
+ strcat(issue, buf);
+ } else {
+ buf[0] = c; buf[1] = '\0';
+ if ((strlen(issue) + strlen(buf)) < size + 1) {
+ size += strlen(buf) + 1;
+ issue = (char *) realloc (issue, size);
+ }
+ strcat(issue, buf);
+ }
+ }
+ return issue;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_issue_modstruct = {
+ "pam_issue",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_lastlog/Makefile b/contrib/libpam/modules/pam_lastlog/Makefile
index e51a72d31f50..e8062714af81 100644
--- a/contrib/libpam/modules/pam_lastlog/Makefile
+++ b/contrib/libpam/modules/pam_lastlog/Makefile
@@ -1,106 +1,19 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:17:14 morgan Exp morgan $
+# $Id: Makefile,v 1.3 2001/02/10 22:33:10 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:17:14 morgan
-# fakeroot fixed
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1997/01/04 20:29:28 morgan
-# Initial revision
-#
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-#
-
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-TITLE=pam_lastlog
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-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
+include ../../Make.Rules
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
+ifeq ($(HAVE_LIBUTIL),yes)
+ MODULE_SIMPLE_EXTRALIBS += -lutil
endif
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_lastlog
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_lastlog/pam_lastlog.c b/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
index 96714f6bc16d..385d96405dd7 100644
--- a/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
+++ b/contrib/libpam/modules/pam_lastlog/pam_lastlog.c
@@ -1,26 +1,17 @@
/* pam_lastlog module */
/*
- * $Id: pam_lastlog.c,v 1.3 1997/04/05 06:18:21 morgan Exp morgan $
+ * $Id: pam_lastlog.c,v 1.3 2001/02/10 22:33:10 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*
* This module does the necessary work to display the last login
* time+date for this user, it then updates this entry for the
* present (login) service.
- *
- * $Log: pam_lastlog.c,v $
- * Revision 1.3 1997/04/05 06:18:21 morgan
- * removed xstrdup - unused
- *
- * Revision 1.2 1997/02/15 17:18:21 morgan
- * removed fixed buffer in logging
- *
- * Revision 1.1 1997/01/04 20:29:28 morgan
- * Initial revision
- *
*/
+#include <security/_pam_aconf.h>
+
#include <fcntl.h>
#include <time.h>
#ifdef HAVE_UTMP_H
diff --git a/contrib/libpam/modules/pam_limits/Makefile b/contrib/libpam/modules/pam_limits/Makefile
index f6a0e07ca48b..695bc02df2f5 100644
--- a/contrib/libpam/modules/pam_limits/Makefile
+++ b/contrib/libpam/modules/pam_limits/Makefile
@@ -1,102 +1,31 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@redhat.com> 1996/09/10
-#
-
-ifeq ($(OS),linux)
-ifeq ($(HAVE_PWDBLIB),yes)
-TITLE=pam_limits
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/limits.conf
-export CONFILE
-
-CFLAGS+=-DLIMITS_FILE=\"$(CONFILE)\"
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
+include ../../Make.Rules
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) -lpwdb
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
+TITLE=pam_limits
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
+ifeq ($(OS),linux)
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+LOCAL_CONFILE=./limits.skel
+INSTALLED_CONFILE=$(SCONFIGD)/limits.conf
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
+CFLAGS += $(DEFS)
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
else
+
include ../dont_makefile
-endif
-else
-include ../dont_makefile
+
endif
diff --git a/contrib/libpam/modules/pam_limits/README b/contrib/libpam/modules/pam_limits/README
index 06a6857a8135..2398334b91e7 100644
--- a/contrib/libpam/modules/pam_limits/README
+++ b/contrib/libpam/modules/pam_limits/README
@@ -4,9 +4,10 @@ pam_limits module:
THEORY OF OPERATION:
-First, make a root-only-readable file (/etc/limits by default or LIMITS_FILE
-defined Makefile) that describes the resource limits you wish to impose. No
-limits are imposed on UID 0 accounts.
+First, make a root-only-readable file (/etc/security/limits.conf by
+default or INSTALLED_CONFILE defined Makefile) that describes the
+resource limits you wish to impose. No limits are imposed on UID 0
+accounts.
Each line describes a limit for a user in the form:
@@ -18,9 +19,10 @@ Where:
- a group name, with @group syntax
- the wildcard *, for default entry
-<type> can have the two values:
- - "soft" for enforcinf the soft limits
+<type> can have the three values:
+ - "soft" for enforcing the soft limits
- "hard" for enforcing hard limits
+ - "-" for enforcing both soft and hard limits
<item> can be one of the following:
- core - limits the core file size (KB)
@@ -35,15 +37,18 @@ Where:
- as - address space limit
- maxlogins - max number of logins for this user
- maxsyslogins - max number of logins on the system
-
-To completely disable limits for a user (or a group), a single dash (-)
-will do (Example: 'bin -', '@admin -'). Please remember that individual
-limits have priority over group limits, so if you impose no limits for 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 item and
+value fields then the module will never enforce any limits on the
+specified user/group etc. .
+
+Please remember that individual limits have priority over group
+limits, so if you impose no limits for admin group, but one of the
+members in this group has a limits line, the user will have its limits
+set according to this line.
Also, please note that all limit settings are set PER LOGIN. They are
-not global, nor are they permanent (the session only)
+not global, nor are they permanent (they apply for the session only).
In the LIMITS_FILE, the # character introduces a comment - the rest of the
line is ignored.
@@ -68,6 +73,12 @@ ARGUMENTS RECOGNIZED:
conf=/path/to/file the limits configuration file if different from the
one set at compile time.
+ 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.
+
MODULE SERVICES PROVIDED:
session _open_session and _close_session (blank)
diff --git a/contrib/libpam/modules/pam_limits/limits.skel b/contrib/libpam/modules/pam_limits/limits.skel
index ea57e42513e4..5ddd9b4c38e5 100644
--- a/contrib/libpam/modules/pam_limits/limits.skel
+++ b/contrib/libpam/modules/pam_limits/limits.skel
@@ -26,6 +26,7 @@
# - nproc - max number of processes
# - as - address space limit
# - maxlogins - max number of logins for this user
+# - priority - the priority to run user process with
#
#<domain> <type> <item> <value>
#
diff --git a/contrib/libpam/modules/pam_limits/pam_limits.c b/contrib/libpam/modules/pam_limits/pam_limits.c
index 179c43028b4e..7a5ec472579c 100644
--- a/contrib/libpam/modules/pam_limits/pam_limits.c
+++ b/contrib/libpam/modules/pam_limits/pam_limits.c
@@ -1,6 +1,8 @@
/*
* pam_limits - impose resource limits when opening a user session
*
+ * 1.6 - modified for PLD (added process priority settings)
+ * by Marcin Korzonek <mkorz@shadow.eu.org
* 1.5 - Elliot Lee's "max system logins patch"
* 1.4 - addressed bug in configuration file parser
* 1.3 - modified the configuration file format
@@ -15,9 +17,10 @@
#error THIS CODE IS KNOWN TO WORK ONLY ON LINUX !!!
#endif
+#include <security/_pam_aconf.h>
+
#include <stdio.h>
#include <unistd.h>
-#define __USE_POSIX2
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
@@ -26,11 +29,15 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/resource.h>
+
#include <utmp.h>
#ifndef UT_USER /* some systems have ut_name instead of ut_user */
#define UT_USER ut_user
#endif
+#include <grp.h>
+#include <pwd.h>
+
/* Module defines */
#define LINE_LENGTH 1024
@@ -39,23 +46,28 @@
#define LIMITS_DEF_DEFAULT 2 /* limit was set by an default entry */
#define LIMITS_DEF_NONE 3 /* this limit was not set yet */
-/* internal data */
-static char conf_file[BUFSIZ];
-
struct user_limits_struct {
int src_soft;
int src_hard;
struct rlimit limit;
};
-static struct user_limits_struct limits[RLIM_NLIMITS];
-static int login_limit; /* the max logins limit */
-static int login_limit_def; /* which entry set the login limit */
-static int flag_numsyslogins; /* whether to limit logins only for a
- specific user or to count all logins */
+/* internal data */
+struct pam_limit_s {
+ int login_limit; /* the max logins limit */
+ int login_limit_def; /* which entry set the login limit */
+ int flag_numsyslogins; /* whether to limit logins only for a
+ specific user or to count all logins */
+ int priority; /* the priority to run user process with */
+ struct user_limits_struct limits[RLIM_NLIMITS];
+ char conf_file[BUFSIZ];
+};
#define LIMIT_LOGIN RLIM_NLIMITS+1
#define LIMIT_NUMSYSLOGINS RLIM_NLIMITS+2
+
+#define LIMIT_PRI RLIM_NLIMITS+3
+
#define LIMIT_SOFT 1
#define LIMIT_HARD 2
@@ -63,7 +75,6 @@ static int flag_numsyslogins; /* whether to limit logins only for a
#include <security/pam_modules.h>
#include <security/_pam_macros.h>
-#include <pwdb/pwdb_map.h>
/* logging */
static void _pam_log(int err, const char *format, ...)
@@ -80,8 +91,9 @@ static void _pam_log(int err, const char *format, ...)
/* argument parsing */
#define PAM_DEBUG_ARG 0x0001
+#define PAM_DO_SETREUID 0x0002
-static int _pam_parse(int argc, const char **argv)
+static int _pam_parse(int argc, const char **argv, struct pam_limit_s *pl)
{
int ctrl=0;
@@ -93,7 +105,9 @@ static int _pam_parse(int argc, const char **argv)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
else if (!strncmp(*argv,"conf=",5))
- strcpy(conf_file,*argv+5);
+ strcpy(pl->conf_file,*argv+5);
+ else if (!strncmp(*argv,"change_uid",10))
+ ctrl |= PAM_DO_SETREUID;
else {
_pam_log(LOG_ERR,"pam_parse: unknown option; %s",*argv);
}
@@ -104,15 +118,18 @@ static int _pam_parse(int argc, const char **argv)
/* limits stuff */
-#ifndef LIMITS_FILE
-#define LIMITS_FILE "/etc/security/limits.conf"
+#ifdef DEFAULT_CONF_FILE
+# define LIMITS_FILE DEFAULT_CONF_FILE
+#else
+# define LIMITS_FILE "/etc/security/limits.conf"
#endif
#define LIMIT_ERR 1 /* error setting a limit */
#define LOGIN_ERR 2 /* too many logins err */
/* Counts the number of user logins and check against the limit*/
-static int check_logins(const char *name, int limit, int ctrl)
+static int check_logins(const char *name, int limit, int ctrl,
+ struct pam_limit_s *pl)
{
struct utmp *ut;
unsigned int count;
@@ -137,7 +154,7 @@ static int check_logins(const char *name, int limit, int ctrl)
#endif
if (ut->UT_USER[0] == '\0')
continue;
- if (!flag_numsyslogins
+ if (!pl->flag_numsyslogins
&& strncmp(name, ut->UT_USER, sizeof(ut->UT_USER)) != 0)
continue;
if (++count >= limit)
@@ -212,65 +229,61 @@ static int is_on_group(const char *user_name, const char *group_name)
return 0;
}
-static int init_limits(void)
+static int init_limits(struct pam_limit_s *pl)
{
+ int i;
int retval = PAM_SUCCESS;
D(("called."));
- retval |= getrlimit(RLIMIT_CPU, &limits[RLIMIT_CPU].limit);
- limits[RLIMIT_CPU].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_CPU].src_hard = LIMITS_DEF_NONE;
+ for(i = 0; i < RLIM_NLIMITS; i++)
+ retval |= getrlimit(i, &pl->limits[i].limit);
+
+ pl->limits[RLIMIT_CPU].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CPU].src_hard = LIMITS_DEF_NONE;
+
+ pl->limits[RLIMIT_FSIZE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_FSIZE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_FSIZE, &limits[RLIMIT_FSIZE].limit);
- limits[RLIMIT_FSIZE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_FSIZE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_DATA].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_DATA].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_DATA, &limits[RLIMIT_DATA].limit);
- limits[RLIMIT_DATA].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_DATA].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_STACK].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_STACK].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_STACK, &limits[RLIMIT_STACK].limit);
- limits[RLIMIT_STACK].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_STACK].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CORE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_CORE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_CORE, &limits[RLIMIT_CORE].limit);
- limits[RLIMIT_CORE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_CORE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_RSS].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_RSS].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_RSS, &limits[RLIMIT_RSS].limit);
- limits[RLIMIT_RSS].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_RSS].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NPROC].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NPROC].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_NPROC, &limits[RLIMIT_NPROC].limit);
- limits[RLIMIT_NPROC].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_NPROC].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NOFILE].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_NOFILE].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_NOFILE, &limits[RLIMIT_NOFILE].limit);
- limits[RLIMIT_NOFILE].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_NOFILE].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_MEMLOCK].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_MEMLOCK].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_MEMLOCK, &limits[RLIMIT_MEMLOCK].limit);
- limits[RLIMIT_MEMLOCK].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_MEMLOCK].src_hard = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_AS].src_soft = LIMITS_DEF_NONE;
+ pl->limits[RLIMIT_AS].src_hard = LIMITS_DEF_NONE;
- retval |= getrlimit(RLIMIT_AS, &limits[RLIMIT_AS].limit);
- limits[RLIMIT_AS].src_soft = LIMITS_DEF_NONE;
- limits[RLIMIT_AS].src_hard = LIMITS_DEF_NONE;
+ pl->priority = 0;
+ pl->login_limit = -2;
+ pl->login_limit_def = LIMITS_DEF_NONE;
- login_limit = -2;
- login_limit_def = LIMITS_DEF_NONE;
return retval;
}
static void process_limit(int source, const char *lim_type,
const char *lim_item, const char *lim_value,
- int ctrl)
+ int ctrl, struct pam_limit_s *pl)
{
int limit_item;
int limit_type = 0;
long limit_value;
- char **endptr = (char **) &lim_value;
+ const char **endptr = &lim_value;
const char *value_orig = lim_value;
if (ctrl & PAM_DEBUG_ARG)
@@ -299,10 +312,12 @@ static void process_limit(int source, const char *lim_type,
limit_item = RLIMIT_AS;
else if (strcmp(lim_item, "maxlogins") == 0) {
limit_item = LIMIT_LOGIN;
- flag_numsyslogins = 0;
+ pl->flag_numsyslogins = 0;
} else if (strcmp(lim_item, "maxsyslogins") == 0) {
limit_item = LIMIT_NUMSYSLOGINS;
- flag_numsyslogins = 1;
+ pl->flag_numsyslogins = 1;
+ } else if (strcmp(lim_item, "priority") == 0) {
+ limit_item = LIMIT_PRI;
} else {
_pam_log(LOG_DEBUG,"unknown limit item '%s'", lim_item);
return;
@@ -349,38 +364,47 @@ static void process_limit(int source, const char *lim_type,
break;
}
- if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS) {
- if (limit_type & LIMIT_SOFT)
- if (limits[limit_item].src_soft < source)
+ if (limit_item != LIMIT_LOGIN && limit_item != LIMIT_NUMSYSLOGINS
+ && limit_item != LIMIT_PRI
+ ) {
+ if (limit_type & LIMIT_SOFT) {
+ if (pl->limits[limit_item].src_soft < source) {
return;
- else {
- limits[limit_item].limit.rlim_cur = limit_value;
- limits[limit_item].src_soft = source;
+ } else {
+ pl->limits[limit_item].limit.rlim_cur = limit_value;
+ pl->limits[limit_item].src_soft = source;
}
- if (limit_type & LIMIT_HARD)
- if (limits[limit_item].src_hard < source)
+ }
+ if (limit_type & LIMIT_HARD) {
+ if (pl->limits[limit_item].src_hard < source) {
return;
- else {
- limits[limit_item].limit.rlim_max = limit_value;
- limits[limit_item].src_hard = source;
+ } else {
+ pl->limits[limit_item].limit.rlim_max = limit_value;
+ pl->limits[limit_item].src_hard = source;
}
- } else
- if (login_limit_def < source)
- return;
- else {
- login_limit = limit_value;
- login_limit_def = source;
- }
-
- return;
+ }
+ } else
+ if (limit_item == LIMIT_PRI) {
+ /* additional check */
+ pl->priority = ((limit_value>0)?limit_value:0);
+ } else {
+ if (pl->login_limit_def < source) {
+ return;
+ } else {
+ pl->login_limit = limit_value;
+ pl->login_limit_def = source;
+ }
+ }
+ return;
}
-static int parse_config_file(const char *uname, int ctrl)
+static int parse_config_file(const char *uname, int ctrl,
+ struct pam_limit_s *pl)
{
FILE *fil;
char buf[LINE_LENGTH];
-#define CONF_FILE (conf_file[0])?conf_file:LIMITS_FILE
+#define CONF_FILE (pl->conf_file[0])?pl->conf_file:LIMITS_FILE
/* check for the LIMITS_FILE */
if (ctrl & PAM_DEBUG_ARG)
_pam_log(LOG_DEBUG,"reading settings from '%s'", CONF_FILE);
@@ -428,6 +452,9 @@ static int parse_config_file(const char *uname, int ctrl)
memset(value, 0, sizeof(value));
i = sscanf(buf,"%s%s%s%s", domain, ltype, item, value);
+ D(("scanned line[%d]: domain[%s], ltype[%s], item[%s], value[%s]",
+ i, domain, ltype, item, value));
+
for(j=0; j < strlen(domain); j++)
domain[j]=tolower(domain[j]);
for(j=0; j < strlen(ltype); j++)
@@ -439,36 +466,56 @@ static int parse_config_file(const char *uname, int ctrl)
if (i == 4) { /* a complete line */
if (strcmp(uname, domain) == 0) /* this user have a limit */
- process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl);
+ process_limit(LIMITS_DEF_USER, ltype, item, value, ctrl, pl);
else if (domain[0]=='@') {
if (is_on_group(uname, domain+1))
- process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl);
+ process_limit(LIMITS_DEF_GROUP, ltype, item, value, ctrl,
+ pl);
} else if (strcmp(domain, "*") == 0)
- process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl);
- } else
- _pam_log(LOG_DEBUG,"invalid line '%s'", buf);
+ process_limit(LIMITS_DEF_DEFAULT, ltype, item, value, ctrl,
+ pl);
+ } else if (i == 2 && ltype[0] == '-') { /* Probably a no-limit line */
+ if (strcmp(uname, domain) == 0) {
+ _pam_log(LOG_DEBUG, "no limits for '%s'", uname);
+ fclose(fil);
+ return PAM_IGNORE;
+ } else if (domain[0] == '@' && is_on_group(uname, domain+1)) {
+ _pam_log(LOG_DEBUG, "no limits for '%s' in group '%s'",
+ uname, domain+1);
+ fclose(fil);
+ return PAM_IGNORE;
+ }
+ } else {
+ _pam_log(LOG_DEBUG,"invalid line '%s' - skipped", buf);
+ }
}
fclose(fil);
return PAM_SUCCESS;
}
-static int setup_limits(const char * uname, int ctrl)
+static int setup_limits(const char * uname, int ctrl, struct pam_limit_s *pl)
{
int i;
int retval = PAM_SUCCESS;
for (i=0; i<RLIM_NLIMITS; i++) {
- if (limits[i].limit.rlim_cur > limits[i].limit.rlim_max)
- limits[i].limit.rlim_cur = limits[i].limit.rlim_max;
- retval |= setrlimit(i, &limits[i].limit);
+ if (pl->limits[i].limit.rlim_cur > pl->limits[i].limit.rlim_max)
+ pl->limits[i].limit.rlim_cur = pl->limits[i].limit.rlim_max;
+ retval |= setrlimit(i, &pl->limits[i].limit);
}
if (retval != PAM_SUCCESS)
retval = LIMIT_ERR;
- if (login_limit > 0) {
- if (check_logins(uname, login_limit, ctrl) == LOGIN_ERR)
+
+ retval=setpriority(PRIO_PROCESS, 0, pl->priority);
+
+ if (retval != PAM_SUCCESS)
+ retval = LIMIT_ERR;
+
+ if (pl->login_limit > 0) {
+ if (check_logins(uname, pl->login_limit, ctrl, pl) == LOGIN_ERR)
retval |= LOGIN_ERR;
- } else if (login_limit == 0)
+ } else if (pl->login_limit == 0)
retval |= LOGIN_ERR;
return retval;
}
@@ -481,12 +528,13 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
char *user_name;
struct passwd *pwd;
int ctrl;
-
+ struct pam_limit_s pl;
+
D(("called."));
- memset(conf_file, 0, sizeof(conf_file));
-
- ctrl = _pam_parse(argc, argv);
+ memset(&pl, 0, sizeof(pl));
+
+ ctrl = _pam_parse(argc, argv, &pl);
retval = pam_get_item( pamh, PAM_USER, (void*) &user_name );
if ( user_name == NULL || retval != PAM_SUCCESS ) {
_pam_log(LOG_CRIT, "open_session - error recovering username");
@@ -511,19 +559,25 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t *pamh, int flags,
return PAM_SUCCESS;
}
- retval = init_limits();
+ retval = init_limits(&pl);
if (retval != PAM_SUCCESS) {
- _pam_log(LOG_WARNING, "can not initialize");
+ _pam_log(LOG_WARNING, "cannot initialize");
return PAM_IGNORE;
}
- retval = parse_config_file(pwd->pw_name,ctrl);
+ retval = parse_config_file(pwd->pw_name, ctrl, &pl);
+ if (retval == PAM_IGNORE) {
+ D(("the configuration file has an applicable '<domain> -' entry"));
+ return PAM_SUCCESS;
+ }
if (retval != PAM_SUCCESS) {
_pam_log(LOG_WARNING, "error parsing the configuration file");
return PAM_IGNORE;
}
-
- retval = setup_limits(pwd->pw_name, ctrl);
+
+ if (ctrl & PAM_DO_SETREUID)
+ setreuid(pwd->pw_uid, -1);
+ retval = setup_limits(pwd->pw_name, ctrl, &pl);
if (retval & LOGIN_ERR) {
printf("\nToo many logins for '%s'\n",pwd->pw_name);
sleep(2);
diff --git a/contrib/libpam/modules/pam_listfile/Makefile b/contrib/libpam/modules/pam_listfile/Makefile
index 02940390b333..c5447c949cf7 100644
--- a/contrib/libpam/modules/pam_listfile/Makefile
+++ b/contrib/libpam/modules/pam_listfile/Makefile
@@ -1,84 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_listfile
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_listfile
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_listfile/pam_listfile.c b/contrib/libpam/modules/pam_listfile/pam_listfile.c
index e54b12aaec0c..2f4f3d0bf98a 100644
--- a/contrib/libpam/modules/pam_listfile/pam_listfile.c
+++ b/contrib/libpam/modules/pam_listfile/pam_listfile.c
@@ -1,39 +1,16 @@
/*
- * $Id: pam_listfile.c,v 1.6 1997/04/05 06:38:35 morgan Exp $
- *
- * $Log: pam_listfile.c,v $
- * Revision 1.6 1997/04/05 06:38:35 morgan
- * reformat mostly
- *
- * Revision 1.5 1997/02/15 17:29:41 morgan
- * removed fixed length buffer in logging
- *
- * Revision 1.4 1997/01/04 20:32:10 morgan
- * ammendments for pam_listfile handling
- *
- * Revision 1.3 1996/11/10 21:02:08 morgan
- * compiles with .53
- *
- * Revision 1.2 1996/09/05 06:22:58 morgan
- * Michael's patches
+ * $Id: pam_listfile.c,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
*
*/
/*
- * by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
- * July 25, 1996.
- * This code shamelessly ripped from the pam_rootok module.
+ * by Elliot Lee <sopwith@redhat.com>, Red Hat Software. July 25, 1996.
+ * log refused access error christopher mccrory <chrismcc@netus.com> 1998/7/11
+ *
+ * This code began life as the pam_rootok module.
*/
-#ifdef linux
-# define _SVID_SOURCE
-# define _BSD_SOURCE
-# define __USE_BSD
-# define __USE_SVID
-# define __USE_MISC
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
#include <stdlib.h>
@@ -64,15 +41,15 @@
/* some syslogging */
+#define LOCAL_LOG_PREFIX "PAM-listfile: "
+
static void _pam_log(int err, const char *format, ...)
{
va_list args;
-
+
va_start(args, format);
- openlog("PAM-listfile", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
+ vsyslog(LOG_AUTH | err, format, args);
va_end(args);
- closelog();
}
/* checks if a user is on a list of members */
@@ -223,36 +200,41 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
strncpy(apply_val,myval,sizeof(apply_val)-1);
}
} else {
- _pam_log(LOG_ERR,"Unknown option: %s",mybuf);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Unknown option: %s",mybuf);
return onerr;
}
}
if(!citem) {
- _pam_log(LOG_ERR,"Unknown item or item not specified");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Unknown item or item not specified");
return onerr;
} else if(!ifname) {
- _pam_log(LOG_ERR,"List filename not specified");
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "List filename not specified");
return onerr;
} else if(sense == 2) {
- _pam_log(LOG_ERR,"Unknown sense or sense not specified");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Unknown sense or sense not specified");
return onerr;
} else if(
(apply_type==APPLY_TYPE_NONE) ||
((apply_type!=APPLY_TYPE_NULL) && (*apply_val=='\0'))
) {
- _pam_log(LOG_ERR,"Invalid usage for apply= parameter");
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX "Invalid usage for apply= parameter");
return onerr;
}
/* Check if it makes sense to use the apply= parameter */
if (apply_type != APPLY_TYPE_NULL) {
if((citem==PAM_USER) || (citem==PAM_RUSER)) {
- _pam_log(LOG_WARNING,"Non-sense use for apply= parameter");
+ _pam_log(LOG_WARNING,
+ LOCAL_LOG_PREFIX "Non-sense use for apply= parameter");
apply_type=APPLY_TYPE_NULL;
}
if(extitem && (extitem==EI_GROUP)) {
- _pam_log(LOG_WARNING,"Non-sense use for apply= parameter");
+ _pam_log(LOG_WARNING,
+ LOCAL_LOG_PREFIX "Non-sense use for apply= parameter");
apply_type=APPLY_TYPE_NULL;
}
}
@@ -269,7 +251,8 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(strcmp(user_name, apply_val)) {
/* Does not apply to this user */
#ifdef DEBUG
- _pam_log(LOG_DEBUG,"don't apply: apply=%s, user=%s",
+ _pam_log(LOG_DEBUG,
+ LOCAL_LOG_PREFIX "don't apply: apply=%s, user=%s",
apply_val,user_name);
#endif /* DEBUG */
return PAM_IGNORE;
@@ -278,7 +261,9 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(!is_on_group(user_name,apply_val)) {
/* Not a member of apply= group */
#ifdef DEBUG
- _pam_log(LOG_DEBUG,"don't apply: %s not a member of group %s",
+ _pam_log(LOG_DEBUG,
+ LOCAL_LOG_PREFIX
+ "don't apply: %s not a member of group %s",
user_name,apply_val);
#endif /* DEBUG */
return PAM_IGNORE;
@@ -331,18 +316,21 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
endpwent();
break;
default:
- _pam_log(LOG_ERR,"Internal weirdness, unknown extended item %d",
+ _pam_log(LOG_ERR,
+ LOCAL_LOG_PREFIX
+ "Internal weirdness, unknown extended item %d",
extitem);
return onerr;
}
}
#ifdef DEBUG
- _pam_log(LOG_INFO,"Got file = %s, item = %d, value = %s, sense = %d",
+ _pam_log(LOG_INFO,
+ LOCAL_LOG_PREFIX
+ "Got file = %s, item = %d, value = %s, sense = %d",
ifname, citem, citemp, sense);
#endif
if(lstat(ifname,&fileinfo)) {
- _pam_log(LOG_ERR,
- "Couldn't open %s",ifname);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Couldn't open %s",ifname);
return onerr;
}
@@ -350,7 +338,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
|| !S_ISREG(fileinfo.st_mode)) {
/* If the file is world writable or is not a
normal file, return error */
- _pam_log(LOG_ERR,
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX
"%s is either world writable or not a normal file",
ifname);
return PAM_AUTH_ERR;
@@ -360,7 +348,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
if(inf == NULL) { /* Check that we opened it successfully */
if (onerr == PAM_SERVICE_ERR) {
/* Only report if it's an error... */
- _pam_log(LOG_ERR, "Error opening %s", ifname);
+ _pam_log(LOG_ERR,LOCAL_LOG_PREFIX "Error opening %s", ifname);
}
return onerr;
}
@@ -394,19 +382,24 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **ar
}
fclose(inf);
free(ifname);
- if(retval) {
+ if ((sense && retval) || (!sense && !retval)) {
#ifdef DEBUG
- syslog(LOG_INFO,"Returning %d, retval = %d",
- sense?PAM_AUTH_ERR:PAM_SUCCESS, retval);
+ _pam_log(LOG_INFO, LOCAL_LOG_PREFIX
+ "Returning PAM_SUCCESS, retval = %d", retval);
#endif
- return sense?PAM_SUCCESS:PAM_AUTH_ERR;
+ return PAM_SUCCESS;
}
else {
+ const char *service, *user_name;
#ifdef DEBUG
- syslog(LOG_INFO,"Returning %d, retval = %d",
- sense?PAM_SUCCESS:PAM_AUTH_ERR, retval);
+ _pam_log(LOG_INFO,LOCAL_LOG_PREFIX
+ "Returning PAM_AUTH_ERR, retval = %d", retval);
#endif
- return sense?PAM_AUTH_ERR:PAM_SUCCESS;
+ (void) pam_get_item(pamh, PAM_SERVICE, (const void **)&service);
+ (void) pam_get_user(pamh, &user_name, NULL);
+ _pam_log(LOG_ALERT,LOCAL_LOG_PREFIX "Refused user %s for service %s",
+ user_name, service);
+ return PAM_AUTH_ERR;
}
}
diff --git a/contrib/libpam/modules/pam_mail/Makefile b/contrib/libpam/modules/pam_mail/Makefile
index 5a402ea4015b..2d9b8e9a30a3 100644
--- a/contrib/libpam/modules/pam_mail/Makefile
+++ b/contrib/libpam/modules/pam_mail/Makefile
@@ -1,107 +1,15 @@
#
-# $Id: Makefile,v 1.3 1997/04/05 06:37:45 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.3 1997/04/05 06:37:45 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.2 1997/02/15 16:07:22 morgan
-# optional libpwdb compilation
-#
-# Revision 1.1 1997/01/04 20:32:52 morgan
-# Initial revision
-#
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/12/8
-#
-
-TITLE=pam_mail
-
-ifndef STATIC
-ifeq ($(HAVE_PWDBLIB),yes)
-CFLAGS += -DWANT_PWDB
-EXTRALIB = -lpwdb
-endif
-endif
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
+include ../../Make.Rules
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALIB)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS) $(EXTRALIB)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_mail
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_mail/README b/contrib/libpam/modules/pam_mail/README
new file mode 100644
index 000000000000..155bd1db66dc
--- /dev/null
+++ b/contrib/libpam/modules/pam_mail/README
@@ -0,0 +1,17 @@
+This is the README for pam_mail
+-------------------------------
+
+This PAM module tells the User that he has new/unread email.
+
+Options for:
+auth: for authentication it provides pam_authenticate() and
+ pam_setcred() hooks.
+
+ "debug" write more information to syslog
+ "dir=maildir" users mailbox is maildir/<login>
+ "hash=count" mail directory hash depth
+ "close" print message also on logout
+ "nopen" print message not on login
+ "noenv" don't set the MAIL environment variable
+ "empty" also print message if user has no mail
+
diff --git a/contrib/libpam/modules/pam_mail/pam_mail.c b/contrib/libpam/modules/pam_mail/pam_mail.c
index 15160f3d5208..df00315ab304 100644
--- a/contrib/libpam/modules/pam_mail/pam_mail.c
+++ b/contrib/libpam/modules/pam_mail/pam_mail.c
@@ -1,29 +1,14 @@
/* pam_mail module */
/*
- * $Id: pam_mail.c,v 1.2 1997/02/15 16:06:14 morgan Exp morgan $
+ * $Id: pam_mail.c,v 1.3 2000/12/04 20:59:13 baggins Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
* $HOME additions by David Kinchlea <kinch@kinch.ark.com> 1997/1/7
- *
- * $Log: pam_mail.c,v $
- * Revision 1.2 1997/02/15 16:06:14 morgan
- * session -> setcred, also added "~"=$HOME
- *
- * Revision 1.1 1997/01/04 20:33:02 morgan
- * Initial revision
+ * mailhash additions by Chris Adams <cadams@ro.com> 1998/7/11
*/
-#define DEFAULT_MAIL_DIRECTORY "/var/spool/mail"
-#define MAIL_FILE_FORMAT "%s/%s"
-#define MAIL_ENV_NAME "MAIL"
-#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
-#define YOUR_MAIL_FORMAT "You have %s mail in %s"
-
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <ctype.h>
#include <pwd.h>
@@ -35,11 +20,20 @@
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
+#include <dirent.h>
#ifdef WANT_PWDB
#include <pwdb/pwdb_public.h>
#endif
+#define DEFAULT_MAIL_DIRECTORY PAM_PATH_MAILDIR
+#define MAIL_FILE_FORMAT "%s%s/%s"
+#define MAIL_ENV_NAME "MAIL"
+#define MAIL_ENV_FORMAT MAIL_ENV_NAME "=%s"
+#define YOUR_MAIL_VERBOSE_FORMAT "You have %s mail in %s."
+#define YOUR_MAIL_STANDARD_FORMAT "You have %smail."
+#define NO_MAIL_STANDARD_FORMAT "No mail."
+
/*
* here, we make a definition for the externally accessible function
* in this file (this definition is required for static a module
@@ -47,6 +41,7 @@
* modules include file to define the function prototypes.
*/
+#define PAM_SM_SESSION
#define PAM_SM_AUTH
#include <security/pam_modules.h>
@@ -67,16 +62,19 @@ static void _log_err(int err, const char *format, ...)
/* argument parsing */
-#define PAM_DEBUG_ARG 01
-#define PAM_NO_LOGIN 02
-#define PAM_LOGOUT_TOO 04
-#define PAM_NEW_MAIL_DIR 010
-#define PAM_MAIL_SILENT 020
-#define PAM_NO_ENV 040
-#define PAM_HOME_MAIL 0100
-#define PAM_EMPTY_TOO 0200
-
-static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_NO_LOGIN 0x0002
+#define PAM_LOGOUT_TOO 0x0004
+#define PAM_NEW_MAIL_DIR 0x0010
+#define PAM_MAIL_SILENT 0x0020
+#define PAM_NO_ENV 0x0040
+#define PAM_HOME_MAIL 0x0100
+#define PAM_EMPTY_TOO 0x0200
+#define PAM_STANDARD_MAIL 0x0400
+#define PAM_QUIET_MAIL 0x1000
+
+static int _pam_parse(int flags, int argc, const char **argv, char **maildir,
+ int *hashcount)
{
int ctrl=0;
@@ -84,6 +82,8 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
ctrl |= PAM_MAIL_SILENT;
}
+ *hashcount = 0;
+
/* step through arguments */
for (; argc-- > 0; ++argv) {
@@ -91,6 +91,10 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
if (!strcmp(*argv,"debug"))
ctrl |= PAM_DEBUG_ARG;
+ else if (!strcmp(*argv,"quiet"))
+ ctrl |= PAM_QUIET_MAIL;
+ else if (!strcmp(*argv,"standard"))
+ ctrl |= PAM_STANDARD_MAIL | PAM_EMPTY_TOO;
else if (!strncmp(*argv,"dir=",4)) {
*maildir = x_strdup(4+*argv);
if (*maildir != NULL) {
@@ -100,6 +104,12 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
_log_err(LOG_CRIT,
"failed to duplicate mail directory - ignored");
}
+ } else if (!strncmp(*argv,"hash=",5)) {
+ char *ep = NULL;
+ *hashcount = strtol(*argv+5,&ep,10);
+ if (!ep || (*hashcount < 0)) {
+ *hashcount = 0;
+ }
} else if (!strcmp(*argv,"close")) {
ctrl |= PAM_LOGOUT_TOO;
} else if (!strcmp(*argv,"nopen")) {
@@ -113,6 +123,11 @@ static int _pam_parse(int flags, int argc, const char **argv, char **maildir)
}
}
+ if ((*hashcount != 0) && !(ctrl & PAM_NEW_MAIL_DIR)) {
+ *maildir = x_strdup(DEFAULT_MAIL_DIRECTORY);
+ ctrl |= PAM_NEW_MAIL_DIR;
+ }
+
return ctrl;
}
@@ -150,8 +165,8 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
return retval; /* propagate error status */
}
-static int get_folder(pam_handle_t *pamh, int ctrl
- , char **path_mail, char **folder_p)
+static int get_folder(pam_handle_t *pamh, int ctrl,
+ char **path_mail, char **folder_p, int hashcount)
{
int retval;
const char *user, *path;
@@ -184,6 +199,9 @@ static int get_folder(pam_handle_t *pamh, int ctrl
return PAM_ABORT;
}
ctrl |= PAM_HOME_MAIL;
+ if (hashcount != 0) {
+ _log_err(LOG_ALERT, "can't do hash= and home directory mail");
+ }
}
} else {
path = DEFAULT_MAIL_DIRECTORY;
@@ -195,14 +213,29 @@ static int get_folder(pam_handle_t *pamh, int ctrl
folder = malloc(sizeof(MAIL_FILE_FORMAT)
+strlen(pwd->pw_dir)+strlen(path));
} else {
- folder = malloc(sizeof(MAIL_FILE_FORMAT)+strlen(path)+strlen(user));
+ folder = malloc(sizeof(MAIL_FILE_FORMAT)+strlen(path)+strlen(user)
+ +2*hashcount);
}
if (folder != NULL) {
if (ctrl & PAM_HOME_MAIL) {
- sprintf(folder, MAIL_FILE_FORMAT, pwd->pw_dir, path);
+ sprintf(folder, MAIL_FILE_FORMAT, pwd->pw_dir, "", path);
} else {
- sprintf(folder, MAIL_FILE_FORMAT, path, user);
+ int i;
+ char *hash = malloc(2*hashcount+1);
+
+ if (hash) {
+ for (i = 0; i < hashcount; i++) {
+ hash[2*i] = '/';
+ hash[2*i+1] = user[i];
+ }
+ hash[2*i] = '\0';
+ sprintf(folder, MAIL_FILE_FORMAT, path, hash, user);
+ _pam_overwrite(hash);
+ _pam_drop(hash);
+ } else {
+ sprintf(folder, "error");
+ }
}
D(("folder =[%s]", folder));
}
@@ -226,17 +259,52 @@ static int get_folder(pam_handle_t *pamh, int ctrl
static const char *get_mail_status(int ctrl, const char *folder)
{
- const char *type;
+ const char *type = NULL;
+ static char dir[256];
struct stat mail_st;
-
- if (stat(folder, &mail_st) == 0 && mail_st.st_size > 0) {
- type = (mail_st.st_atime < mail_st.st_mtime) ? "new":"old" ;
- } else if (ctrl & PAM_EMPTY_TOO) {
- type = "no";
- } else {
- type = NULL;
+ struct dirent **namelist;
+ int i;
+
+ if (stat(folder, &mail_st) == 0) {
+ if (S_ISDIR(mail_st.st_mode)) { /* Assume Maildir format */
+ sprintf(dir, "%.250s/new", folder);
+ i = scandir(dir, &namelist, 0, alphasort);
+ if (i > 2) {
+ type = "new";
+ while (--i)
+ free(namelist[i]);
+ } else {
+ while (--i >= 0)
+ free(namelist[i]);
+ sprintf(dir, "%.250s/cur", folder);
+ i = scandir(dir, &namelist, 0, alphasort);
+ if (i > 2) {
+ type = "old";
+ while (--i)
+ free(namelist[i]);
+ } else if (ctrl & PAM_EMPTY_TOO) {
+ while (--i >= 0)
+ free(namelist[i]);
+ type = "no";
+ } else {
+ type = NULL;
+ }
+ }
+ } else {
+ if (mail_st.st_size > 0) {
+ if (mail_st.st_atime < mail_st.st_mtime) /* new */
+ type = (ctrl & PAM_STANDARD_MAIL) ? "new " : "new";
+ else /* old */
+ type = (ctrl & PAM_STANDARD_MAIL) ? "" : "old";
+ } else if (ctrl & PAM_EMPTY_TOO) {
+ type = "no";
+ } else {
+ type = NULL;
+ }
+ }
}
+ memset(dir, 0, 256);
memset(&mail_st, 0, sizeof(mail_st));
D(("user has %s mail in %s folder", type, folder));
return type;
@@ -247,17 +315,29 @@ static int report_mail(pam_handle_t *pamh, int ctrl
{
int retval;
- if (!(ctrl & PAM_MAIL_SILENT)) {
+ if (!(ctrl & PAM_MAIL_SILENT) || ((ctrl & PAM_QUIET_MAIL) && strcmp(type, "new"))) {
char *remark;
- remark = malloc(sizeof(YOUR_MAIL_FORMAT)+strlen(type)+strlen(folder));
+ if (ctrl & PAM_STANDARD_MAIL)
+ if (!strcmp(type, "no"))
+ remark = malloc(strlen(NO_MAIL_STANDARD_FORMAT)+1);
+ else
+ remark = malloc(strlen(YOUR_MAIL_STANDARD_FORMAT)+strlen(type)+1);
+ else
+ remark = malloc(strlen(YOUR_MAIL_VERBOSE_FORMAT)+strlen(type)+strlen(folder)+1);
if (remark == NULL) {
retval = PAM_BUF_ERR;
} else {
struct pam_message msg[1], *mesg[1];
struct pam_response *resp=NULL;
- sprintf(remark, YOUR_MAIL_FORMAT, type, folder);
+ if (ctrl & PAM_STANDARD_MAIL)
+ if (!strcmp(type, "no"))
+ sprintf(remark, NO_MAIL_STANDARD_FORMAT);
+ else
+ sprintf(remark, YOUR_MAIL_STANDARD_FORMAT, type);
+ else
+ sprintf(remark, YOUR_MAIL_VERBOSE_FORMAT, type, folder);
mesg[0] = &msg[0];
msg[0].msg_style = PAM_TEXT_INFO;
@@ -279,28 +359,51 @@ static int report_mail(pam_handle_t *pamh, int ctrl
return retval;
}
-/* --- authentication management functions (only) --- */
+static int _do_mail(pam_handle_t *, int, int, const char **, int);
-/*
- * Cannot use mail to authenticate yourself
- */
+/* --- authentication functions --- */
PAM_EXTERN
-int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
- ,const char **argv)
+int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc,
+ const char **argv)
{
return PAM_IGNORE;
}
-/*
- * MAIL is a "credential"
- */
+/* Checking mail as part of authentication */
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED)))
+ return PAM_IGNORE;
+ return _do_mail(pamh,flags,argc,argv,(flags & PAM_ESTABLISH_CRED));
+}
+
+/* --- session management functions --- */
+
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t *pamh,int flags,int argc
+ ,const char **argv)
+{
+ return _do_mail(pamh,flags,argc,argv,0);;
+}
+/* Checking mail as part of the session management */
PAM_EXTERN
-int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
- , const char **argv)
+int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
{
- int retval, ctrl;
+ return _do_mail(pamh,flags,argc,argv,1);
+}
+
+
+/* --- The Beaf (Tm) --- */
+
+static int _do_mail(pam_handle_t *pamh, int flags, int argc,
+ const char **argv, int est)
+{
+ int retval, ctrl, hashcount;
char *path_mail=NULL, *folder;
const char *type;
@@ -309,17 +412,16 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
* the user has any new mail.
*/
- ctrl = _pam_parse(flags, argc, argv, &path_mail);
+ ctrl = _pam_parse(flags, argc, argv, &path_mail, &hashcount);
/* Do we have anything to do? */
- if (!(flags & (PAM_ESTABLISH_CRED|PAM_DELETE_CRED))) {
+ if (flags & PAM_SILENT)
return PAM_SUCCESS;
- }
/* which folder? */
- retval = get_folder(pamh, ctrl, &path_mail, &folder);
+ retval = get_folder(pamh, ctrl, &path_mail, &folder, hashcount);
if (retval != PAM_SUCCESS) {
D(("failed to find folder"));
return retval;
@@ -327,7 +429,7 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
/* set the MAIL variable? */
- if (!(ctrl & PAM_NO_ENV) && (flags & PAM_ESTABLISH_CRED)) {
+ if (!(ctrl & PAM_NO_ENV) && est) {
char *tmp;
tmp = malloc(strlen(folder)+sizeof(MAIL_ENV_FORMAT));
@@ -357,24 +459,20 @@ int pam_sm_setcred(pam_handle_t *pamh, int flags, int argc
* OK. we've got the mail folder... what about its status?
*/
- if (((flags & PAM_ESTABLISH_CRED) && !(ctrl & PAM_NO_LOGIN))
- || ((flags & PAM_DELETE_CRED) && (ctrl & PAM_LOGOUT_TOO))) {
+ if ((est && !(ctrl & PAM_NO_LOGIN))
+ || (!est && (ctrl & PAM_LOGOUT_TOO))) {
type = get_mail_status(ctrl, folder);
if (type != NULL) {
retval = report_mail(pamh, ctrl, type, folder);
type = NULL;
}
}
-
- /*
- * Delete environment variable?
- */
-
- if (flags & PAM_DELETE_CRED) {
+
+ /* Delete environment variable? */
+ if (!est)
(void) pam_putenv(pamh, MAIL_ENV_NAME);
- }
- _pam_overwrite(folder); /* clean up */
+ _pam_overwrite(folder); /* clean up */
_pam_drop(folder);
/* indicate success or failure */
@@ -391,8 +489,8 @@ struct pam_module _pam_mail_modstruct = {
pam_sm_authenticate,
pam_sm_setcred,
NULL,
- NULL,
- NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
NULL,
};
diff --git a/contrib/libpam/modules/pam_mkhomedir/Makefile b/contrib/libpam/modules/pam_mkhomedir/Makefile
new file mode 100644
index 000000000000..f017f4a469ec
--- /dev/null
+++ b/contrib/libpam/modules/pam_mkhomedir/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.3 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_mkhomedir
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c b/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c
new file mode 100644
index 000000000000..ec05993dfa1e
--- /dev/null
+++ b/contrib/libpam/modules/pam_mkhomedir/pam_mkhomedir.c
@@ -0,0 +1,370 @@
+/* PAM Make Home Dir module
+
+ This module will create a users home directory if it does not exist
+ when the session begins. This allows users to be present in central
+ database (such as nis, kerb or ldap) without using a distributed
+ file system or pre-creating a large number of directories.
+
+ Here is a sample /etc/pam.d/login file for Debian GNU/Linux
+ 2.1:
+
+ auth requisite pam_securetty.so
+ auth sufficient pam_ldap.so
+ auth required pam_pwdb.so
+ auth optional pam_group.so
+ auth optional pam_mail.so
+ account requisite pam_time.so
+ account sufficient pam_ldap.so
+ account required pam_pwdb.so
+ session required pam_mkhomedir.so skel=/etc/skel/ umask=0022
+ session required pam_pwdb.so
+ session optional pam_lastlog.so
+ password required pam_pwdb.so
+
+ Released under the GNU LGPL version 2 or later
+ Originally written by Jason Gunthorpe <jgg@debian.org> Feb 1999
+ Structure taken from pam_lastlogin by Andrew Morgan
+ <morgan@parc.power.net> 1996
+ */
+
+/* I want snprintf dammit */
+#define _GNU_SOURCE 1
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <dirent.h>
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_SESSION
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+/* argument parsing */
+#define MKHOMEDIR_DEBUG 020 /* keep quiet about things */
+#define MKHOMEDIR_QUIET 040 /* keep quiet about things */
+
+static unsigned int UMask = 0022;
+static char SkelDir[BUFSIZ] = "/etc/skel";
+
+/* some syslogging */
+static void _log_err(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("PAM-mkhomedir", LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static int _pam_parse(int flags, int argc, const char **argv)
+{
+ int ctrl = 0;
+
+ /* does the appliction require quiet? */
+ if ((flags & PAM_SILENT) == PAM_SILENT)
+ ctrl |= MKHOMEDIR_QUIET;
+
+ /* step through arguments */
+ for (; argc-- > 0; ++argv)
+ {
+ if (!strcmp(*argv, "silent"))
+ {
+ ctrl |= MKHOMEDIR_QUIET;
+ }
+ else if (!strncmp(*argv,"umask=",6))
+ UMask = strtol(*argv+6,0,0);
+ else if (!strncmp(*argv,"skel=",5))
+ strcpy(SkelDir,*argv+5);
+ else
+ {
+ _log_err(LOG_ERR, "unknown option; %s", *argv);
+ }
+ }
+
+ D(("ctrl = %o", ctrl));
+ return ctrl;
+}
+
+/* This common function is used to send a message to the applications
+ conversion function. Our only use is to ask the application to print
+ an informative message that we are creating a home directory */
+static int converse(pam_handle_t * pamh, int ctrl, int nargs
+ ,struct pam_message **message
+ ,struct pam_response **response)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("begin to converse"));
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS)
+ {
+
+ retval = conv->conv(nargs, (const struct pam_message **) message
+ ,response, conv->appdata_ptr);
+
+ D(("returned from application's conversation function"));
+
+ if (retval != PAM_SUCCESS && (ctrl & MKHOMEDIR_DEBUG))
+ {
+ _log_err(LOG_DEBUG, "conversation failure [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+
+ }
+ else
+ {
+ _log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+
+ D(("ready to return from module conversation"));
+
+ return retval; /* propagate error status */
+}
+
+/* Ask the application to display a short text string for us. */
+static int make_remark(pam_handle_t * pamh, int ctrl, const char *remark)
+{
+ int retval;
+
+ if ((ctrl & MKHOMEDIR_QUIET) != MKHOMEDIR_QUIET)
+ {
+ struct pam_message msg[1], *mesg[1];
+ struct pam_response *resp = NULL;
+
+ mesg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ msg[0].msg = remark;
+
+ retval = converse(pamh, ctrl, 1, mesg, &resp);
+
+ msg[0].msg = NULL;
+ if (resp)
+ {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ else
+ {
+ D(("keeping quiet"));
+ retval = PAM_SUCCESS;
+ }
+
+ D(("returning %s", pam_strerror(pamh, retval)));
+ return retval;
+}
+
+/* Do the actual work of creating a home dir */
+static int create_homedir(pam_handle_t * pamh, int ctrl,
+ const struct passwd *pwd)
+{
+ char *remark;
+ DIR *D;
+ struct dirent *Dir;
+
+ /* Some scratch space */
+ remark = malloc(BUFSIZ);
+ if (remark == NULL)
+ {
+ D(("no memory for last login remark"));
+ return PAM_BUF_ERR;
+ }
+
+ /* Mention what is happening, if the notification fails that is OK */
+ if (snprintf(remark,BUFSIZ,"Creating home directory '%s'.",
+ pwd->pw_dir) == -1)
+ return PAM_PERM_DENIED;
+
+ make_remark(pamh, ctrl, remark);
+
+ /* Crete the home directory */
+ if (mkdir(pwd->pw_dir,0700) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to create home directory %s",pwd->pw_dir);
+ return PAM_PERM_DENIED;
+ }
+ if (chmod(pwd->pw_dir,0777 & (~UMask)) != 0 ||
+ chown(pwd->pw_dir,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to chance perms on home directory %s",pwd->pw_dir);
+ return PAM_PERM_DENIED;
+ }
+
+ /* See if we need to copy the skel dir over. */
+ if (SkelDir[0] == 0)
+ {
+ free(remark);
+ return PAM_SUCCESS;
+ }
+
+ /* Scan the directory */
+ D = opendir(SkelDir);
+ if (D == 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to read directory %s",SkelDir);
+ return PAM_PERM_DENIED;
+ }
+
+ for (Dir = readdir(D); Dir != 0; Dir = readdir(D))
+ {
+ int SrcFd;
+ int DestFd;
+ int Res;
+ struct stat St;
+
+ /* Skip some files.. */
+ if (strcmp(Dir->d_name,".") == 0 ||
+ strcmp(Dir->d_name,"..") == 0)
+ continue;
+
+ /* Check if it is a directory */
+ snprintf(remark,BUFSIZ,"%s/%s",SkelDir,Dir->d_name);
+ if (stat(remark,&St) != 0)
+ continue;
+ if (S_ISDIR(St.st_mode))
+ {
+ snprintf(remark,BUFSIZ,"%s/%s",pwd->pw_dir,Dir->d_name);
+ if (mkdir(remark,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ chmod(remark,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ chown(remark,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to change perms on copy %s",remark);
+ return PAM_PERM_DENIED;
+ }
+ continue;
+ }
+
+ /* Open the source file */
+ if ((SrcFd = open(remark,O_RDONLY)) < 0 || fstat(SrcFd,&St) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to open src file %s",remark);
+ return PAM_PERM_DENIED;
+ }
+ stat(remark,&St);
+
+ /* Open the dest file */
+ snprintf(remark,BUFSIZ,"%s/%s",pwd->pw_dir,Dir->d_name);
+ if ((DestFd = open(remark,O_WRONLY | O_TRUNC | O_CREAT,0600)) < 0)
+ {
+ close(SrcFd);
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to open dest file %s",remark);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Set the proper ownership and permissions for the module. We make
+ the file a+w and then mask it with the set mask. This preseves
+ execute bits */
+ if (fchmod(DestFd,(St.st_mode | 0222) & (~UMask)) != 0 ||
+ fchown(DestFd,pwd->pw_uid,pwd->pw_gid) != 0)
+ {
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to chang perms on copy %s",remark);
+ return PAM_PERM_DENIED;
+ }
+
+ /* Copy the file */
+ do
+ {
+ Res = read(SrcFd,remark,BUFSIZ);
+ if (Res < 0 || write(DestFd,remark,Res) != Res)
+ {
+ close(SrcFd);
+ close(DestFd);
+ free(remark);
+ _log_err(LOG_DEBUG, "unable to perform IO");
+ return PAM_PERM_DENIED;
+ }
+ }
+ while (Res != 0);
+ close(SrcFd);
+ close(DestFd);
+ }
+
+ free(remark);
+ return PAM_SUCCESS;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_open_session(pam_handle_t * pamh, int flags, int argc
+ ,const char **argv)
+{
+ int retval, ctrl;
+ const char *user;
+ const struct passwd *pwd;
+ struct stat St;
+
+ /* Parse the flag values */
+ ctrl = _pam_parse(flags, argc, argv);
+
+ /* Determine the user name so we can get the home directory */
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &user);
+ if (retval != PAM_SUCCESS || user == NULL || *user == '\0')
+ {
+ _log_err(LOG_NOTICE, "user unknown");
+ return PAM_USER_UNKNOWN;
+ }
+
+ /* Get the password entry */
+ pwd = getpwnam(user);
+ if (pwd == NULL)
+ {
+ D(("couldn't identify user %s", user));
+ return PAM_CRED_INSUFFICIENT;
+ }
+
+ /* Stat the home directory, if something exists then we assume it is
+ correct and return a success*/
+ if (stat(pwd->pw_dir,&St) == 0)
+ return PAM_SUCCESS;
+
+ return create_homedir(pamh,ctrl,pwd);
+}
+
+/* Ignore */
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t * pamh, int flags, int argc
+ ,const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+#ifdef PAM_STATIC
+
+/* static module data */
+struct pam_module _pam_mkhomedir_modstruct =
+{
+ "pam_mkhomedir",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+
+#endif
diff --git a/contrib/libpam/modules/pam_motd/Makefile b/contrib/libpam/modules/pam_motd/Makefile
new file mode 100644
index 000000000000..fb83807a36da
--- /dev/null
+++ b/contrib/libpam/modules/pam_motd/Makefile
@@ -0,0 +1,15 @@
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
+
+include ../../Make.Rules
+
+TITLE=pam_motd
+
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_motd/pam_motd.c b/contrib/libpam/modules/pam_motd/pam_motd.c
new file mode 100644
index 000000000000..2434b2986c9b
--- /dev/null
+++ b/contrib/libpam/modules/pam_motd/pam_motd.c
@@ -0,0 +1,119 @@
+/* pam_motd module */
+
+/*
+ * Modified for pam_motd by Ben Collins <bcollins@debian.org>
+ *
+ * Based off of:
+ * $Id: pam_motd.c,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
+ *
+ * Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+ *
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <pwd.h>
+
+#include <security/_pam_macros.h>
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_SESSION
+#define DEFAULT_MOTD "/etc/motd"
+
+#include <security/pam_modules.h>
+
+/* --- session management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ int retval = PAM_IGNORE;
+ int fd;
+ char *mtmp=NULL, *motd_path=NULL;
+ struct pam_conv *conversation;
+ struct pam_message message;
+ struct pam_message *pmessage = &message;
+ struct pam_response *resp = NULL;
+ struct stat st;
+
+ if (flags & PAM_SILENT) {
+ return retval;
+ }
+
+ for (; argc-- > 0; ++argv) {
+ if (!strncmp(*argv,"motd=",5)) {
+ motd_path = (char *) strdup(5+*argv);
+ if (motd_path != NULL) {
+ D(("set motd path: %s", motd_path));
+ } else {
+ D(("failed to duplicate motd path - ignored"));
+ }
+ }
+ }
+
+ if (motd_path == NULL)
+ motd_path = DEFAULT_MOTD;
+
+ message.msg_style = PAM_TEXT_INFO;
+
+ if ((fd = open(motd_path, O_RDONLY, 0)) >= 0) {
+ /* fill in message buffer with contents of motd */
+ if ((fstat(fd, &st) < 0) || !st.st_size)
+ return retval;
+ message.msg = mtmp = malloc(st.st_size+1);
+ /* if malloc failed... */
+ if (!message.msg) return retval;
+ read(fd, mtmp, st.st_size);
+ if (mtmp[st.st_size-1] == '\n')
+ mtmp[st.st_size-1] = '\0';
+ else
+ mtmp[st.st_size] = '\0';
+ close(fd);
+ /* Use conversation function to give user contents of motd */
+ pam_get_item(pamh, PAM_CONV, (const void **)&conversation);
+ conversation->conv(1, (const struct pam_message **)&pmessage,
+ &resp, conversation->appdata_ptr);
+ free(mtmp);
+ if (resp)
+ _pam_drop_reply(resp, 1);
+ }
+
+ return retval;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_motd_modstruct = {
+ "pam_motd",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+
+#endif
+
+/* end of module definition */
diff --git a/contrib/libpam/modules/pam_nologin/Makefile b/contrib/libpam/modules/pam_nologin/Makefile
index 0769bb993120..2ad38ffd9609 100644
--- a/contrib/libpam/modules/pam_nologin/Makefile
+++ b/contrib/libpam/modules/pam_nologin/Makefile
@@ -1,86 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-TITLE=pam_nologin
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- mkdir -p ./dynamic
-endif
-ifdef STATIC
- mkdir -p ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- mkdir -p $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- install -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_nologin
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_nologin/README b/contrib/libpam/modules/pam_nologin/README
index ab7ccd7d9803..9b00e6923868 100644
--- a/contrib/libpam/modules/pam_nologin/README
+++ b/contrib/libpam/modules/pam_nologin/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/10/25 03:19:36 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
#
This module always lets root in; it lets other users in only if the file
diff --git a/contrib/libpam/modules/pam_nologin/pam_nologin.c b/contrib/libpam/modules/pam_nologin/pam_nologin.c
index 2788dcf8f39a..1359c18bfaf6 100644
--- a/contrib/libpam/modules/pam_nologin/pam_nologin.c
+++ b/contrib/libpam/modules/pam_nologin/pam_nologin.c
@@ -1,24 +1,10 @@
/* pam_nologin module */
/*
- * $Id: pam_nologin.c,v 1.4 1997/04/05 06:36:47 morgan Exp morgan $
+ * $Id: pam_nologin.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Michael K. Johnson <johnsonm@redhat.com> 1996/10/24
*
- * $Log: pam_nologin.c,v $
- * Revision 1.4 1997/04/05 06:36:47 morgan
- * display message when the user is unknown
- *
- * Revision 1.3 1996/12/01 03:00:54 morgan
- * added prototype to conversation, gave static structure name of module
- *
- * Revision 1.2 1996/11/10 21:02:31 morgan
- * compile against .53
- *
- * Revision 1.1 1996/10/25 03:19:36 morgan
- * Initial revision
- *
- *
*/
#include <stdio.h>
diff --git a/contrib/libpam/modules/pam_permit/Makefile b/contrib/libpam/modules/pam_permit/Makefile
index 823b62472e35..49f3b3dd5e20 100644
--- a/contrib/libpam/modules/pam_permit/Makefile
+++ b/contrib/libpam/modules/pam_permit/Makefile
@@ -1,126 +1,15 @@
#
-# $Id: Makefile,v 1.8 1997/04/05 06:33:25 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.8 1997/04/05 06:33:25 morgan
-# fakeroot
-#
-# Revision 1.7 1997/02/15 19:02:27 morgan
-# updated email address
-#
-# Revision 1.6 1996/11/10 20:14:34 morgan
-# cross platform support
-#
-# Revision 1.5 1996/09/05 06:32:45 morgan
-# ld --> gcc
-#
-# Revision 1.4 1996/05/26 15:49:25 morgan
-# make dynamic and static dirs
-#
-# Revision 1.3 1996/05/26 04:04:26 morgan
-# automated static support
-#
-# Revision 1.2 1996/03/16 17:56:38 morgan
-# tidied up
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Convenient defaults for compiling independently of the full source
-# tree.
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-endif
-
-#
-#
+include ../../Make.Rules
TITLE=pam_permit
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-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) $(CFLAGS) $(STATIC) $(TARGET_ARCH) -c $< -o $@
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-endif
-
-ifdef DYNAMIC
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-endif
-
-ifdef STATIC
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_permit/README b/contrib/libpam/modules/pam_permit/README
index da179a34829c..52e7364e8753 100644
--- a/contrib/libpam/modules/pam_permit/README
+++ b/contrib/libpam/modules/pam_permit/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/03/16 18:12:51 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
#
this module always returns PAM_SUCCESS, it ignores all options.
diff --git a/contrib/libpam/modules/pam_permit/pam_permit.c b/contrib/libpam/modules/pam_permit/pam_permit.c
index 1bdd5644a63b..46e36eb97c24 100644
--- a/contrib/libpam/modules/pam_permit/pam_permit.c
+++ b/contrib/libpam/modules/pam_permit/pam_permit.c
@@ -1,20 +1,10 @@
/* pam_permit module */
/*
- * $Id: pam_permit.c,v 1.5 1997/02/15 19:03:15 morgan Exp $
+ * $Id: pam_permit.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
*
- * $Log: pam_permit.c,v $
- * Revision 1.5 1997/02/15 19:03:15 morgan
- * fixed email address
- *
- * Revision 1.4 1997/02/15 16:03:10 morgan
- * force a name for user
- *
- * Revision 1.3 1996/06/02 08:10:14 morgan
- * updated for new static protocol
- *
*/
#define DEFAULT_USER "nobody"
diff --git a/contrib/libpam/modules/pam_pwdb/BUGS b/contrib/libpam/modules/pam_pwdb/BUGS
index 397f367b5372..d51686e51d76 100644
--- a/contrib/libpam/modules/pam_pwdb/BUGS
+++ b/contrib/libpam/modules/pam_pwdb/BUGS
@@ -1,8 +1,3 @@
-$Id: BUGS,v 1.2 1996/09/05 06:36:16 morgan Exp $
-
-$Log: BUGS,v $
-Revision 1.2 1996/09/05 06:36:16 morgan
-revised for .52 to be released
-
+$Id: BUGS,v 1.2 2000/12/04 19:02:34 baggins Exp $
As of Linux-PAM-0.52 this is new. No known bugs yet.
diff --git a/contrib/libpam/modules/pam_pwdb/CHANGELOG b/contrib/libpam/modules/pam_pwdb/CHANGELOG
index 0cb21879120b..a36140319933 100644
--- a/contrib/libpam/modules/pam_pwdb/CHANGELOG
+++ b/contrib/libpam/modules/pam_pwdb/CHANGELOG
@@ -1,4 +1,4 @@
-$Header: /home/morgan/pam/Linux-PAM-0.52/modules/pam_unix/RCS/CHANGELOG,v 1.1 1996/08/29 13:23:29 morgan Exp $
+$Id: CHANGELOG,v 1.1.1.1 2000/06/20 22:11:46 agmorgan Exp $
Tue Apr 23 12:28:09 EDT 1996 (Alexander O. Yuriev alex@bach.cis.temple.edu)
diff --git a/contrib/libpam/modules/pam_pwdb/Makefile b/contrib/libpam/modules/pam_pwdb/Makefile
index 7428bb439040..ec66f9e8269c 100644
--- a/contrib/libpam/modules/pam_pwdb/Makefile
+++ b/contrib/libpam/modules/pam_pwdb/Makefile
@@ -1,4 +1,4 @@
-# $Id: Makefile,v 1.7 1997/04/05 06:28:50 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:04 agmorgan Exp $
#
# This Makefile controls a build process of the pam_unix module
# for Linux-PAM. You should not modify this Makefile.
@@ -7,42 +7,20 @@
# <morgan@parc.power.net> 1996/11/6
#
-#
-# Note, the STATIC module is commented out because it doesn't work.
-# please fix!
-#
+include ../../Make.Rules
-ifndef FULL_LINUX_PAM_SOURCE_TREE
-export DYNAMIC=-DPAM_DYNAMIC
-export CC=gcc
-export CFLAGS=-O2 -Dlinux -DLINUX_PAM \
- -ansi -D_POSIX_SOURCE -Wall -Wwrite-strings \
- -Wpointer-arith -Wcast-qual -Wcast-align -Wtraditional \
- -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline \
- -Wshadow -pedantic -fPIC
-export MKDIR=mkdir -p
-export LD_D=gcc -shared -Xlinker -x
-export HAVE_PWDBLIB=yes
-endif
+ifeq ($(HAVE_LIBPWDB),yes)
-ifeq ($(HAVE_PWDBLIB),yes)
+EXTRALS += -lpwdb
+EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
+
+ifeq ($(HAVE_LIBCRYPT),yes)
+ EXTRALS += -lcrypt
+endif
TITLE=pam_pwdb
CHKPWD=pwdb_chkpwd
-# compilation flags
-EXTRAS=
-# extra object files
-PLUS=
-# extra files that may be needed to be created
-CREATE=
-
-# NOTE: this module links dynamically to the libpwdb library.
-EXTRALS += -lpwdb
-EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
-
-########################### don't edit below ##########################
-
LIBSRC = $(TITLE).c
LIBOBJ = $(TITLE).o
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
@@ -50,7 +28,7 @@ LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBDEPS = pam_unix_acct.-c pam_unix_auth.-c pam_unix_passwd.-c \
pam_unix_sess.-c pam_unix_pwupd.-c support.-c bigcrypt.-c
-PLUS += md5.o md5_crypt.o
+PLUS += md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o
CFLAGS += $(EXTRAS)
ifdef DYNAMIC
@@ -73,11 +51,28 @@ info:
@echo "*** Building PAM_pwdb module..."
@echo
-$(CHKPWD): pwdb_chkpwd.o md5.o md5_crypt.o
+$(CHKPWD): pwdb_chkpwd.o md5_good.o md5_broken.o \
+ md5_crypt_good.o md5_crypt_broken.o
$(CC) -o $(CHKPWD) $^ -lpwdb
pwdb_chkpwd.o: pwdb_chkpwd.c pam_unix_md.-c bigcrypt.-c
+md5_good.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_broken.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_good.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_broken.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
dirs:
ifdef DYNAMIC
@$(MKDIR) ./dynamic
@@ -111,7 +106,7 @@ ifdef DYNAMIC
$(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
endif
$(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
- $(INSTALL) -m 4555 -o root -g root $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
+ $(INSTALL) -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
remove:
rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
@@ -119,37 +114,11 @@ remove:
clean:
rm -f $(CHKPWD) $(LIBOBJD) $(LIBOBJS) $(MOREDELS) core *~ *.o *.so
-
-extraclean: clean
rm -f *.a *.o *.so *.bak
+ rm -fr dynamic static
else
include ../dont_makefile
endif
-
-#####################################################################
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:28:50 morgan
-# fakeroot
-#
-# Revision 1.6 1997/02/15 17:25:32 morgan
-# update for .56 . extra commands for new helper binary
-#
-# Revision 1.5 1997/01/04 20:39:08 morgan
-# conditional on having libpwdb
-#
-# Revision 1.4 1996/12/01 03:02:03 morgan
-# changed banner, removed linking libraries
-#
-# Revision 1.3 1996/11/10 20:14:42 morgan
-# cross platform support
-#
-# Revision 1.2 1996/09/05 06:36:49 morgan
-# options added and use of LD altered
-#
-# Revision 1.1 1996/08/29 13:23:29 morgan
-# Initial revision
-#
-#
diff --git a/contrib/libpam/modules/pam_pwdb/README b/contrib/libpam/modules/pam_pwdb/README
index 351a706008e9..4f420855cded 100644
--- a/contrib/libpam/modules/pam_pwdb/README
+++ b/contrib/libpam/modules/pam_pwdb/README
@@ -7,7 +7,7 @@ passwords.
the license suggests -- use at your own risk.]
So far as I am concerned this module is now pretty stable. If you find
-any bugs, PLEASE tell me! <morgan@parc.power.net>
+any bugs, PLEASE tell me! <morgan@linux.kernel.org>
Options recognized by this module are as follows:
@@ -38,4 +38,4 @@ should read the source to find the appropriate #define that you will
need.
---------------------
-Andrew Morgan <morgan@parc.power.net>
+Andrew Morgan <morgan@linux.kernel.org>
diff --git a/contrib/libpam/modules/pam_pwdb/TODO b/contrib/libpam/modules/pam_pwdb/TODO
index 23eb4c163d08..520a262ec13c 100644
--- a/contrib/libpam/modules/pam_pwdb/TODO
+++ b/contrib/libpam/modules/pam_pwdb/TODO
@@ -1,4 +1,4 @@
-$Id: TODO,v 1.3 1996/11/10 21:03:21 morgan Exp $
+$Id: TODO,v 1.1.1.1 2000/06/20 22:11:47 agmorgan Exp $
* get NIS working
* .. including "nonis" argument
diff --git a/contrib/libpam/modules/pam_pwdb/md5.c b/contrib/libpam/modules/pam_pwdb/md5.c
index fdfbdd88f389..4428294178ff 100644
--- a/contrib/libpam/modules/pam_pwdb/md5.c
+++ b/contrib/libpam/modules/pam_pwdb/md5.c
@@ -1,4 +1,4 @@
-/* $Id: md5.c,v 1.1 1996/09/05 06:43:31 morgan Exp $
+/* $Id: md5.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* This code implements the MD5 message-digest algorithm.
* The algorithm is due to Ron Rivest. This code was
@@ -15,10 +15,6 @@
* needed on buffers full of bytes, and then call MD5Final, which
* will fill a supplied 16-byte array with the digest.
*
- * $Log: md5.c,v $
- * Revision 1.1 1996/09/05 06:43:31 morgan
- * Initial revision
- *
*/
#include <string.h>
@@ -27,13 +23,13 @@
#ifndef HIGHFIRST
#define byteReverse(buf, len) /* Nothing */
#else
-void byteReverse(unsigned char *buf, unsigned longs);
+static void byteReverse(unsigned char *buf, unsigned longs);
#ifndef ASM_MD5
/*
* Note: this code is harmless on little-endian machines.
*/
-void byteReverse(unsigned char *buf, unsigned longs)
+static void byteReverse(unsigned char *buf, unsigned longs)
{
uint32 t;
do {
@@ -50,7 +46,7 @@ void byteReverse(unsigned char *buf, unsigned longs)
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
* initialization constants.
*/
-void MD5Init(struct MD5Context *ctx)
+void MD5Name(MD5Init)(struct MD5Context *ctx)
{
ctx->buf[0] = 0x67452301U;
ctx->buf[1] = 0xefcdab89U;
@@ -65,7 +61,7 @@ void MD5Init(struct MD5Context *ctx)
* Update context to reflect the concatenation of another buffer full
* of bytes.
*/
-void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
{
uint32 t;
@@ -90,7 +86,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
}
memcpy(p, buf, t);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
buf += t;
len -= t;
}
@@ -99,7 +95,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
while (len >= 64) {
memcpy(ctx->in, buf, 64);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
buf += 64;
len -= 64;
}
@@ -113,7 +109,7 @@ void MD5Update(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
* Final wrapup - pad to 64-byte boundary with the bit pattern
* 1 0* (64-bit count of bits processed, MSB-first)
*/
-void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
{
unsigned count;
unsigned char *p;
@@ -134,7 +130,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
/* Two lots of padding: Pad the first block to 64 bytes */
memset(p, 0, count);
byteReverse(ctx->in, 16);
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
/* Now fill the next block with 56 bytes */
memset(ctx->in, 0, 56);
@@ -148,7 +144,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
((uint32 *) ctx->in)[14] = ctx->bits[0];
((uint32 *) ctx->in)[15] = ctx->bits[1];
- MD5Transform(ctx->buf, (uint32 *) ctx->in);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
byteReverse((unsigned char *) ctx->buf, 4);
memcpy(digest, ctx->buf, 16);
memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
@@ -173,7 +169,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx)
* reflect the addition of 16 longwords of new data. MD5Update blocks
* the data and converts bytes into longwords for this routine.
*/
-void MD5Transform(uint32 buf[4], uint32 const in[16])
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
{
register uint32 a, b, c, d;
diff --git a/contrib/libpam/modules/pam_pwdb/md5.h b/contrib/libpam/modules/pam_pwdb/md5.h
index 4949ade27e1f..75c4dbac85e1 100644
--- a/contrib/libpam/modules/pam_pwdb/md5.h
+++ b/contrib/libpam/modules/pam_pwdb/md5.h
@@ -1,11 +1,7 @@
#ifndef MD5_H
#define MD5_H
-#ifdef __alpha
typedef unsigned int uint32;
-#else
-typedef unsigned long uint32;
-#endif
struct MD5Context {
uint32 buf[4];
@@ -13,13 +9,17 @@ struct MD5Context {
unsigned char in[64];
};
-void MD5Init(struct MD5Context *);
-void MD5Update(struct MD5Context *, unsigned const char *, unsigned);
-void MD5Final(unsigned char digest[16], struct MD5Context *);
-void MD5Transform(uint32 buf[4], uint32 const in[16]);
-int i64c(int i);
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
-char *crypt_md5(const char *pw, const char *salt);
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
/*
* This is needed to make RSAREF happy on some MS-DOS compilers.
diff --git a/contrib/libpam/modules/pam_pwdb/md5_crypt.c b/contrib/libpam/modules/pam_pwdb/md5_crypt.c
index 88be13b7f001..826087f28093 100644
--- a/contrib/libpam/modules/pam_pwdb/md5_crypt.c
+++ b/contrib/libpam/modules/pam_pwdb/md5_crypt.c
@@ -1,4 +1,4 @@
-/* $Id: md5_crypt.c,v 1.1 1996/09/05 06:43:31 morgan Exp $
+/* $Id: md5_crypt.c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* ----------------------------------------------------------------------------
* "THE BEER-WARE LICENSE" (Revision 42):
@@ -9,10 +9,6 @@
*
* Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
*
- * $Log: md5_crypt.c,v $
- * Revision 1.1 1996/09/05 06:43:31 morgan
- * Initial revision
- *
*/
#include <string.h>
@@ -31,34 +27,12 @@ to64(char *s, unsigned long v, int n)
}
/*
- * i64c - convert an integer to a radix 64 character
- */
-int i64c(int i)
-{
- if (i < 0)
- return ('.');
- else if (i > 63)
- return ('z');
- if (i == 0)
- return ('.');
- if (i == 1)
- return ('/');
- if (i >= 2 && i <= 11)
- return ('0' - 2 + i);
- if (i >= 12 && i <= 37)
- return ('A' - 12 + i);
- if (i >= 38 && i <= 63)
- return ('a' - 38 + i);
- return ('\0');
-}
-
-/*
* UNIX password
*
* Use MD5 for what it is best at...
*/
-char * crypt_md5(const char *pw, const char *salt)
+char * MD5Name(crypt_md5)(const char *pw, const char *salt)
{
const char *magic = "$1$";
/* This string is magic for this algorithm. Having
@@ -84,25 +58,25 @@ char * crypt_md5(const char *pw, const char *salt)
/* get the length of the true salt */
sl = ep - sp;
- MD5Init(&ctx);
+ MD5Name(MD5Init)(&ctx);
/* The password first, since that is what is most unknown */
- MD5Update(&ctx,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw));
/* Then our magic string */
- MD5Update(&ctx,(unsigned const char *)magic,strlen(magic));
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
/* Then the raw salt */
- MD5Update(&ctx,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
/* Then just as many characters of the MD5(pw,salt,pw) */
- MD5Init(&ctx1);
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Update(&ctx1,(unsigned const char *)sp,sl);
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Final(final,&ctx1);
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
for(pl = strlen(pw); pl > 0; pl -= 16)
- MD5Update(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
/* Don't leave anything around in vm they could use. */
memset(final,0,sizeof final);
@@ -110,16 +84,16 @@ char * crypt_md5(const char *pw, const char *salt)
/* Then something really weird... */
for (j=0,i = strlen(pw); i ; i >>= 1)
if(i&1)
- MD5Update(&ctx, (unsigned const char *)final+j, 1);
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
else
- MD5Update(&ctx, (unsigned const char *)pw+j, 1);
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
/* Now make the output string */
strcpy(passwd,magic);
strncat(passwd,sp,sl);
strcat(passwd,"$");
- MD5Final(final,&ctx);
+ MD5Name(MD5Final)(final,&ctx);
/*
* and now, just to make sure things don't run too fast
@@ -127,23 +101,23 @@ char * crypt_md5(const char *pw, const char *salt)
* need 30 seconds to build a 1000 entry dictionary...
*/
for(i=0;i<1000;i++) {
- MD5Init(&ctx1);
+ MD5Name(MD5Init)(&ctx1);
if(i & 1)
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
else
- MD5Update(&ctx1,(unsigned const char *)final,16);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
if(i % 3)
- MD5Update(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
if(i % 7)
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
if(i & 1)
- MD5Update(&ctx1,(unsigned const char *)final,16);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
else
- MD5Update(&ctx1,(unsigned const char *)pw,strlen(pw));
- MD5Final(final,&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
}
p = passwd + strlen(passwd);
diff --git a/contrib/libpam/modules/pam_pwdb/pam_pwdb.c b/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
index a612f74037b4..8c75ac232e18 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
+++ b/contrib/libpam/modules/pam_pwdb/pam_pwdb.c
@@ -1,5 +1,5 @@
/*
- * $Id: pam_pwdb.c,v 1.3 1997/01/04 20:38:33 morgan Exp morgan $
+ * $Id: pam_pwdb.c,v 1.3 2000/11/19 23:54:04 agmorgan Exp $
*
* This is the single file that will be compiled for pam_unix.
* it includes each of the modules that have beed defined in the .-c
@@ -13,37 +13,14 @@
* See the end of this file for Copyright information.
*/
-/*
- * $Log: pam_pwdb.c,v $
- * Revision 1.3 1997/01/04 20:38:33 morgan
- * this is not the unix module!
- *
- * Revision 1.2 1996/12/01 03:03:43 morgan
- * debugging code uses _pam_malloc
- *
- * Revision 1.1 1996/11/10 21:21:24 morgan
- * Initial revision
- *
- * Revision 1.3 1996/09/05 06:44:33 morgan
- * more debugging, fixed static structure name
- *
- * Revision 1.2 1996/09/01 01:05:12 morgan
- * Cristian Gafton's patches.
- *
- * Revision 1.1 1996/08/29 13:22:19 morgan
- * Initial revision
- *
- */
-
static const char rcsid[] =
-"$Id: pam_pwdb.c,v 1.3 1997/01/04 20:38:33 morgan Exp morgan $\n"
+"$Id: pam_pwdb.c,v 1.3 2000/11/19 23:54:04 agmorgan Exp $\n"
" - PWDB Pluggable Authentication module. <morgan@linux.kernel.org>"
;
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+/* #define DEBUG */
+
+#include <security/_pam_aconf.h>
#include <sys/types.h>
#include <stdarg.h>
@@ -56,9 +33,6 @@ static const char rcsid[] =
#include <fcntl.h>
#include <ctype.h>
-#define _SVID_SOURCE
-#define __USE_BSD
-#define _BSD_COMPAT
#include <sys/time.h>
#include <unistd.h>
@@ -100,6 +74,13 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t *pamh, int flags
retval = _unix_auth( pamh, ctrl );
pwdb_end();
+ if ( on(UNIX_LIKE_AUTH, ctrl) ) {
+ D(("recording return code for next time [%d]", retval));
+ pam_set_data(pamh, "pwdb_setcred_return", (void *) retval, NULL);
+ }
+
+ D(("done. [%s]", pam_strerror(pamh, retval)));
+
return retval;
}
@@ -113,9 +94,17 @@ PAM_EXTERN int pam_sm_setcred(pam_handle_t *pamh, int flags
pwdb_start();
ctrl = set_ctrl(flags, argc, argv);
- retval = _unix_set_credentials(pamh, ctrl) ;
+ retval = _unix_set_credentials(pamh, ctrl);
pwdb_end();
+ if ( on(UNIX_LIKE_AUTH, ctrl) ) {
+ int *pretval = &retval;
+
+ D(("recovering return code from auth call"));
+ pam_get_data(pamh, "pwdb_setcred_return", (const void **) pretval);
+ D(("recovered data indicates that old retval was %d", retval));
+ }
+
return retval;
}
@@ -203,6 +192,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags,
retval = _unix_chauthtok(pamh, ctrl);
pwdb_end();
+ D(("done."));
+
return retval;
}
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
index dbd13855ed3c..adcb6538624f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_acct.-c
@@ -1,31 +1,11 @@
/*
- * $Id: pam_unix_acct.-c,v 1.6 1997/01/04 20:37:15 morgan Exp morgan $
- *
- * $Log: pam_unix_acct.-c,v $
- * Revision 1.6 1997/01/04 20:37:15 morgan
- * extra debugging
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:03:57 morgan
- * pwdb conversion
- *
- * Revision 1.3 1996/09/05 06:45:45 morgan
- * tidied shadow acct management
- *
- * Revision 1.2 1996/09/01 01:13:14 morgan
- * Cristian Gafton's patches
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
+ * $Id: pam_unix_acct.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* See end of file for copyright information
*/
static const char rcsid_acct[] =
-"$Id: pam_unix_acct.-c,v 1.6 1997/01/04 20:37:15 morgan Exp morgan $\n"
+"$Id: pam_unix_acct.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB account management <gafton@redhat.com>";
/* the shadow suite has accout managment.. */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
index 4a1eed0d6387..31230394c65f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_auth.-c
@@ -1,25 +1,11 @@
/*
- * $Id: pam_unix_auth.-c,v 1.4 1996/12/01 03:05:54 morgan Exp $
+ * $Id: pam_unix_auth.-c,v 1.1.1.1 2000/06/20 22:11:49 agmorgan Exp $
*
- * $Log: pam_unix_auth.-c,v $
- * Revision 1.4 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.3 1996/11/10 21:04:29 morgan
- * pwdb conversion
- *
- * Revision 1.2 1996/09/05 06:46:53 morgan
- * fixed comments. Added check for null passwd.
- * changed data item name
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
* See end of file for Copyright information.
*/
static const char rcsid_auth[] =
-"$Id: pam_unix_auth.-c,v 1.4 1996/12/01 03:05:54 morgan Exp $: pam_unix_auth.-c,v 1.2 1996/09/05 06:46:53 morgan Exp morgan $\n"
+"$Id: pam_unix_auth.-c,v 1.1.1.1 2000/06/20 22:11:49 agmorgan Exp $: pam_unix_auth.-c,v 1.2 1996/09/05 06:46:53 morgan Exp morgan $\n"
" - PAM_PWDB authentication functions. <morgan@parc.power.net>";
/*
@@ -42,8 +28,15 @@ static int _unix_auth(pam_handle_t *pamh, unsigned int ctrl)
retval = _unix_get_user(pamh, ctrl, NULL, &name);
if (retval != PAM_SUCCESS ) {
- if ( on(UNIX_DEBUG,ctrl) ) {
- _log_err(LOG_DEBUG, "auth could not identify user");
+ if (retval != PAM_CONV_AGAIN) {
+ if ( on(UNIX_DEBUG,ctrl) ) {
+ _log_err(LOG_DEBUG, "auth could not identify user");
+ }
+ } else {
+ D(("pam_get_user/conv() function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ retval to the value that indicates we're happy to resume. */
+ retval = PAM_INCOMPLETE;
}
return retval;
}
@@ -60,18 +53,27 @@ static int _unix_auth(pam_handle_t *pamh, unsigned int ctrl)
retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
, _UNIX_AUTHTOK, &p);
- if (retval != PAM_SUCCESS ) {
- _log_err(LOG_CRIT, "auth could not identify password for [%s]"
- , name);
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_CRIT, "auth could not identify password for [%s]"
+ , name);
+ } else {
+ D(("conversation function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ retval to the value that indicates we're happy to resume. */
+ retval = PAM_INCOMPLETE;
+ }
name = NULL;
return retval;
}
+ D(("user=%s, password=[%s]", name, p));
/* verify the password of this user */
-
retval = _unix_verify_password(pamh, name, p, ctrl);
name = p = NULL;
+ D(("done [%d]", retval));
+
return retval;
}
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
index cd90b0ff339b..d9b2c51b205a 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_md.-c
@@ -25,7 +25,7 @@ struct cfns {
#define N_MDS 1
const static struct cfns cfn_list[N_MDS] = {
- { "$1$", 3, crypt_md5 },
+ { "$1$", 3, Goodcrypt_md5 },
};
static char *_pam_md(const char *key, const char *salt)
@@ -53,3 +53,21 @@ static char *_pam_md(const char *key, const char *salt)
return x; /* this must be deleted elsewhere */
}
+#ifndef PWDB_NO_MD_COMPAT
+static char *_pam_md_compat(const char *key, const char *salt)
+{
+ char *x,*e=NULL;
+
+ D(("called with key='%s', salt='%s'", key, salt));
+
+ if ( !strncmp("$1$", salt, 3) ) {
+ e = Brokencrypt_md5(key, salt);
+ x = x_strdup(e); /* put e in malloc()ed memory */
+ _pam_overwrite(e); /* clean up */
+ } else {
+ x = x_strdup("*");
+ }
+
+ return x; /* this must be deleted elsewhere */
+}
+#endif /* PWDB_NO_MD_COMPAT */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
index 402f7f349f88..eb43bcfa713f 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_passwd.-c
@@ -1,29 +1,7 @@
-/* $Id: pam_unix_passwd.-c,v 1.6 1997/04/05 06:31:06 morgan Exp morgan $ */
-
-/*
- * $Log: pam_unix_passwd.-c,v $
- * Revision 1.6 1997/04/05 06:31:06 morgan
- * mostly a reformat.
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:04:51 morgan
- * pwdb conversion
- *
- * Revision 1.3 1996/09/05 06:48:15 morgan
- * A lot has changed. I'd recommend you study the diff.
- *
- * Revision 1.2 1996/09/01 16:33:27 morgan
- * Cristian Gafton's changes
- *
- * Revision 1.1 1996/08/29 13:21:27 morgan
- * Initial revision
- *
- */
+/* $Id: pam_unix_passwd.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $ */
static const char rcsid_pass[] =
-"$Id: pam_unix_passwd.-c,v 1.6 1997/04/05 06:31:06 morgan Exp morgan $\n"
+"$Id: pam_unix_passwd.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB password module <morgan@parc.power.net>"
;
@@ -42,6 +20,28 @@ static const char rcsid_pass[] =
/* Implementation */
/*
+ * i64c - convert an integer to a radix 64 character
+ */
+static int i64c(int i)
+{
+ if (i < 0)
+ return ('.');
+ else if (i > 63)
+ return ('z');
+ if (i == 0)
+ return ('.');
+ if (i == 1)
+ return ('/');
+ if (i >= 2 && i <= 11)
+ return ('0' - 2 + i);
+ if (i >= 12 && i <= 37)
+ return ('A' - 12 + i);
+ if (i >= 38 && i <= 63)
+ return ('a' - 38 + i);
+ return ('\0');
+}
+
+/*
* FUNCTION: _pam_unix_chauthtok()
*
* this function works in two passes. The first, when UNIX__PRELIM is
@@ -259,15 +259,15 @@ static int _unix_chauthtok(pam_handle_t *pamh, unsigned int ctrl)
unsigned char tmp[16];
int i;
- MD5Init(&ctx);
+ GoodMD5Init(&ctx);
gettimeofday(&tv, (struct timezone *) 0);
- MD5Update(&ctx, (void *) &tv, sizeof tv);
+ GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
i = getpid();
- MD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
i = clock();
- MD5Update(&ctx, (void *) &i, sizeof i);
- MD5Update(&ctx, result, sizeof result);
- MD5Final(tmp, &ctx);
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, result, sizeof result);
+ GoodMD5Final(tmp, &ctx);
strcpy(cp, "$1$"); /* magic for the MD5 */
cp += strlen(cp);
for (i = 0; i < 8; i++)
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
index d50031dcb919..a1fc65ff5163 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_pwupd.-c
@@ -1,19 +1,7 @@
/*
- * $Id: pam_unix_pwupd.-c,v 1.4 1997/01/04 20:35:32 morgan Exp morgan $
+ * $Id: pam_unix_pwupd.-c,v 1.1.1.1 2000/06/20 22:11:51 agmorgan Exp $
*
* This file contains the routines to update the passwd databases.
- *
- * $Log: pam_unix_pwupd.-c,v $
- * Revision 1.4 1997/01/04 20:35:32 morgan
- * minor comment change
- *
- * Revision 1.3 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.2 1996/11/10 21:05:09 morgan
- * pwdb conversion
- *
- *
*/
/* Implementation */
diff --git a/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c b/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
index 49ce96cbd16c..395bd9bba3a7 100644
--- a/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
+++ b/contrib/libpam/modules/pam_pwdb/pam_unix_sess.-c
@@ -1,25 +1,11 @@
/*
- * $Id: pam_unix_sess.-c,v 1.4 1996/12/01 03:05:54 morgan Exp morgan $
- *
- * $Log: pam_unix_sess.-c,v $
- * Revision 1.4 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.3 1996/11/10 21:05:33 morgan
- * pwdb conversion
- *
- * Revision 1.2 1996/09/05 06:49:02 morgan
- * more informative logging
- *
- * Revision 1.1 1996/08/29 13:27:51 morgan
- * Initial revision
- *
+ * $Id: pam_unix_sess.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $
*
* See end for Copyright information
*/
static const char rcsid_sess[] =
-"$Id: pam_unix_sess.-c,v 1.4 1996/12/01 03:05:54 morgan Exp morgan $\n"
+"$Id: pam_unix_sess.-c,v 1.2 2000/12/04 19:02:34 baggins Exp $\n"
" - PAM_PWDB session management. morgan@parc.power.net";
/* Define internal functions */
diff --git a/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c b/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
index 6332eaa7e865..3b3c1d5f0f51 100644
--- a/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
+++ b/contrib/libpam/modules/pam_pwdb/pwdb_chkpwd.c
@@ -1,5 +1,5 @@
/*
- * $Id: pwdb_chkpwd.c,v 1.1 1997/02/15 17:26:18 morgan Exp $
+ * $Id: pwdb_chkpwd.c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
*
* This program is designed to run setuid(root) or with sufficient
* privilege to read all of the unix password databases. It is designed
@@ -11,19 +11,9 @@
*
* Copyright information is located at the end of the file.
*
- * $Log: pwdb_chkpwd.c,v $
- * Revision 1.1 1997/02/15 17:26:18 morgan
- * Initial revision
- *
- * Revision 1.1 1996/11/10 21:20:51 morgan
- * Initial revision
- *
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdarg.h>
#include <stdio.h>
@@ -54,6 +44,7 @@ static void _log_err(int err, const char *format, ...)
closelog();
}
+#define PWDB_NO_MD_COMPAT
#include "pam_unix_md.-c"
static int _unix_verify_passwd(const char *salt, const char *p)
@@ -92,12 +83,12 @@ static int _unix_verify_passwd(const char *salt, const char *p)
return retval;
}
-void main(void)
+int main(int argc, char **argv)
{
const struct pwdb *pw=NULL;
const struct pwdb_entry *pwe=NULL;
char pass[MAXPASS+1];
- int npass;
+ int npass, force_failure=0;
int retval=UNIX_FAILED;
/*
@@ -129,14 +120,26 @@ void main(void)
retval = UNIX_FAILED;
}
if (retval != UNIX_FAILED) {
- retval = pwdb_locate("user", PWDB_DEFAULT, PWDB_NAME_UNKNOWN
- , getuid(), &pw);
+ retval = pwdb_locate("user", PWDB_DEFAULT, PWDB_NAME_UNKNOWN,
+ getuid(), &pw);
}
if (retval != PWDB_SUCCESS) {
_log_err(LOG_ALERT, "could not identify user");
while (pwdb_end() != PWDB_SUCCESS);
exit(UNIX_FAILED);
}
+ if (argc == 2) {
+ if (pwdb_get_entry(pw, "user", &pwe) == PWDB_SUCCESS) {
+ if (pwe == NULL) {
+ force_failure = 1;
+ } else {
+ if (strcmp((const char *) pwe->value, argv[1])) {
+ force_failure = 1;
+ }
+ pwdb_entry_delete(&pwe);
+ }
+ }
+ }
/* read the password from stdin (a pipe from the pam_pwdb module) */
@@ -167,6 +170,10 @@ void main(void)
memset(pass, '\0', MAXPASS); /* clear memory of the password */
while (pwdb_end() != PWDB_SUCCESS);
+ if ((retval != UNIX_FAILED) && force_failure) {
+ retval = UNIX_FAILED;
+ }
+
/* return pass or fail */
exit(retval);
diff --git a/contrib/libpam/modules/pam_pwdb/support.-c b/contrib/libpam/modules/pam_pwdb/support.-c
index 71e212d64195..2b80f960cde7 100644
--- a/contrib/libpam/modules/pam_pwdb/support.-c
+++ b/contrib/libpam/modules/pam_pwdb/support.-c
@@ -1,18 +1,5 @@
/*
- * $Id: support.-c,v 1.7 1997/04/05 06:32:06 morgan Exp morgan $
- *
- * $Log: support.-c,v $
- * Revision 1.7 1997/04/05 06:32:06 morgan
- * new option and also deleted _readto
- *
- * Revision 1.6 1997/02/15 17:27:20 morgan
- * added helper binary to password checking
- *
- * Revision 1.5 1996/12/01 03:05:54 morgan
- * debugging with _pam_macros.h
- *
- * Revision 1.4 1996/11/10 21:06:07 morgan
- * pwdb conversion
+ * $Id: support.-c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
*
* Copyright information at end of file.
*/
@@ -91,8 +78,9 @@ typedef struct {
#define UNIX_NODELAY 18 /* admin does not want a fail-delay */
#define UNIX_UNIX 19 /* wish to use /etc/passwd for pwd */
#define UNIX_BIGCRYPT 20 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 21 /* need to auth for setcred to work */
/* -------------- */
-#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 22 /* number of ctrl arguments defined */
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
@@ -118,8 +106,9 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = {
/* UNIX__SET_DB */ { NULL, _ALL_ON_, 0100000 },
/* UNIX_DEBUG */ { "debug", _ALL_ON_, 0200000 },
/* UNIX_NODELAY */ { "nodelay", _ALL_ON_, 0400000 },
-/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
+/* UNIX_UNIX */ { "unix", _ALL_ON_^(050000), 01000000 },
/* UNIX_BIGCRYPT */ { "bigcrypt", _ALL_ON_^(020000), 02000000 },
+/* UNIX_LIKE_AUTH */ { "likeauth", _ALL_ON_, 04000000 },
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@@ -161,7 +150,7 @@ static int converse(pam_handle_t *pamh, int ctrl, int nargs
, pam_strerror(pamh, retval));
}
- } else {
+ } else if (retval != PAM_CONV_AGAIN) {
_log_err(LOG_ERR, "couldn't obtain coversation function [%s]"
, pam_strerror(pamh, retval));
}
@@ -322,13 +311,13 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
if ( !quiet && !err ) { /* under advisement from Sun,may go away */
/* log the number of authentication failures */
- if ( failure->count != 0 ) {
+ if ( failure->count > 1 ) {
(void) pam_get_item(pamh, PAM_SERVICE
, (const void **)&service);
_log_err(LOG_NOTICE
- , "%d authentication failure%s; %s(uid=%d) -> "
+ , "%d more authentication failure%s; %s(uid=%d) -> "
"%s for %s service"
- , failure->count, failure->count==1 ? "":"s"
+ , failure->count-1, failure->count==2 ? "":"s"
, failure->name
, failure->id
, failure->user
@@ -356,7 +345,8 @@ static void _cleanup_failures(pam_handle_t *pamh, void *fl, int err)
#include <sys/types.h>
#include <sys/wait.h>
-static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
+static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ const char *user)
{
int retval, child, fds[2];
@@ -370,7 +360,7 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* fork */
child = fork();
if (child == 0) {
- static char *args[] = { NULL, NULL };
+ static char *args[] = { NULL, NULL, NULL };
static char *envp[] = { NULL };
/* XXX - should really tidy up PAM here too */
@@ -382,6 +372,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
/* exec binary helper */
args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
+
execve(CHKPWD_HELPER, args, envp);
/* should not get here: exit with error */
@@ -389,13 +381,14 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
exit(PWDB_SUCCESS+1);
} else if (child > 0) {
/* wait for child */
- close(fds[0]);
if (passwd != NULL) { /* send the password to the child */
write(fds[1], passwd, strlen(passwd)+1);
passwd = NULL;
} else {
write(fds[1], "", 1); /* blank password */
}
+ close(fds[0]); /* we close this after the write because we want
+ to avoid a possible SIGPIPE. */
close(fds[1]);
(void) waitpid(child, &retval, 0); /* wait for helper to complete */
retval = (retval == PWDB_SUCCESS) ? PAM_SUCCESS:PAM_AUTH_ERR;
@@ -408,8 +401,8 @@ static int pwdb_run_helper_binary(pam_handle_t *pamh, const char *passwd)
return retval;
}
-static int _unix_verify_password(pam_handle_t *pamh, const char *name
- , const char *p, unsigned int ctrl)
+static int _unix_verify_password(pam_handle_t *pamh, const char *name,
+ const char *p, unsigned int ctrl)
{
const struct pwdb *pw=NULL;
const struct pwdb_entry *pwe=NULL;
@@ -418,6 +411,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
char *pp;
char *data_name;
int retval;
+ int verify_result;
D(("called"));
@@ -474,7 +468,7 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (geteuid()) {
/* we are not root perhaps this is the reason? Run helper */
D(("running helper binary"));
- retval = pwdb_run_helper_binary(pamh, p);
+ retval = pwdb_run_helper_binary(pamh, p, name);
} else {
retval = PAM_AUTHINFO_UNAVAIL;
_log_err(LOG_ALERT, "get passwd; %s", pwdb_strerror(retval));
@@ -491,33 +485,56 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
* clear text...
*/
- if ( ( !salt ) && ( !p ) ) {
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
+ if ( data_name == NULL ) {
+ _log_err(LOG_CRIT, "no memory for data-name");
+ }
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
- /* the stored password is NULL */
+ if ( !( (salt && *salt) || (p && *p) ) ) {
- (void) pwdb_entry_delete(&pwe);
- (void) pwdb_delete(&pw);
+ D(("two null passwords to compare"));
+ /* the stored password is NULL */
+ pp = NULL;
if ( off(UNIX__NONULL, ctrl ) ) { /* this means we've succeeded */
- return PAM_SUCCESS;
+ verify_result = PAM_SUCCESS;
} else {
- return PAM_AUTH_ERR;
+ verify_result = PAM_AUTH_ERR;
}
- }
- pp = _pam_md(p, salt);
- p = NULL; /* no longer needed here */
+ } else if ( !( salt && p ) ) {
- data_name = (char *) malloc(sizeof(FAIL_PREFIX)+strlen(name));
- if ( data_name == NULL ) {
- _log_err(LOG_CRIT, "no memory for data-name");
- }
- strcpy(data_name, FAIL_PREFIX);
- strcpy(data_name + sizeof(FAIL_PREFIX)-1, name);
+ D(("one of the two to compare are NULL"));
+
+ pp = NULL;
+ verify_result = PAM_AUTH_ERR;
+
+ } else {
- /* the moment of truth -- do we agree with the password? */
+ pp = _pam_md(p, salt);
- if ( strcmp( pp, salt ) == 0 ) {
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ _pam_delete(pp);
+ pp = _pam_md_compat(p, salt);
+ if ( strcmp( pp, salt ) == 0 ) {
+ verify_result = PAM_SUCCESS;
+ } else {
+ verify_result = PAM_AUTH_ERR;
+ }
+ }
+
+ p = NULL; /* no longer needed here */
+
+ }
+
+ if ( verify_result == PAM_SUCCESS ) {
retval = PAM_SUCCESS;
if (data_name) { /* reset failures */
@@ -538,7 +555,11 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
if (new != NULL) {
- /* any previous failures for this user ? */
+ new->user = x_strdup(name);
+ new->id = getuid();
+ new->name = x_strdup(getlogin() ? getlogin():"" );
+
+ /* any previous failures for this user ? */
pam_get_data(pamh, data_name, (const void **)&old );
if (old != NULL) {
@@ -547,11 +568,19 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
retval = PAM_MAXTRIES;
}
} else {
+ const char *service=NULL;
+ (void) pam_get_item(pamh, PAM_SERVICE
+ , (const void **)&service);
+ _log_err(LOG_NOTICE
+ , "authentication failure; %s(uid=%d) -> "
+ "%s for %s service"
+ , new->name
+ , new->id
+ , new->user
+ , service == NULL ? "**unknown**":service
+ );
new->count = 1;
}
- new->user = x_strdup(name);
- new->id = getuid();
- new->name = x_strdup(getlogin() ? getlogin():"" );
pam_set_data(pamh, data_name, new, _cleanup_failures);
@@ -568,6 +597,8 @@ static int _unix_verify_password(pam_handle_t *pamh, const char *name
_pam_delete(data_name);
_pam_delete(pp);
+ D(("done [%d].", retval));
+
return retval;
}
@@ -596,8 +627,9 @@ static int _unix_get_user(pam_handle_t *pamh, unsigned int ctrl
* alphanumeric character.
*/
- if (!isalnum(**user)) {
- if (on(UNIX_DEBUG,ctrl) || **user) {
+ if (*user == NULL || !isalnum(**user)) {
+ D(("bad username"));
+ if (on(UNIX_DEBUG,ctrl)) {
_log_err(LOG_ERR, "bad username [%s]", *user);
}
return PAM_USER_UNKNOWN;
@@ -872,7 +904,7 @@ static int _pam_unix_approve_pass(pam_handle_t *pamh
}
/* ****************************************************************** *
- * Copyright (c) Andrew G. Morgan, <morgan@parc.power.net> 1996.
+ * Copyright (c) Andrew G. Morgan 1996-8.
* Copyright (c) Alex O. Yuriev, 1996.
* Copyright (c) Cristian Gafton 1996.
*
diff --git a/contrib/libpam/modules/pam_radius/Makefile b/contrib/libpam/modules/pam_radius/Makefile
index a74b911f4e3b..aa149d3ee9b5 100644
--- a/contrib/libpam/modules/pam_radius/Makefile
+++ b/contrib/libpam/modules/pam_radius/Makefile
@@ -8,13 +8,15 @@
# STATIC modules are not supported
#
+include ../../Make.Rules
+
TITLE=pam_radius
CONFD=$(CONFIGED)/security
export CONFD
CONFILE=$(CONFD)/radius.conf
export CONFILE
-ifeq ($(HAVE_PWDBLIB),yes)
+ifeq ($(HAVE_LIBPWDB),yes)
#
@@ -41,11 +43,6 @@ endif
####################### don't edit below #######################
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
all: dirs $(LIBSHARED) $(LIBSTATIC) register
dirs:
@@ -85,9 +82,8 @@ remove:
clean:
rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
rm -f *.a *.o *.so *.bak dynamic/* static/*
+ rm -rf dynamic static
.c.o:
$(CC) $(CFLAGS) -c $<
diff --git a/contrib/libpam/modules/pam_radius/pam_radius.h b/contrib/libpam/modules/pam_radius/pam_radius.h
index 72b1da8aa0cb..67230243eed8 100644
--- a/contrib/libpam/modules/pam_radius/pam_radius.h
+++ b/contrib/libpam/modules/pam_radius/pam_radius.h
@@ -1,12 +1,17 @@
+/*
+ * $Id: pam_radius.h,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+ */
#ifndef PAM_RADIUS_H
#define PAM_RADIUS_H
-#define _GNU_SOURCE
-#include <features.h>
+#include <security/_pam_aconf.h>
#include <stdio.h>
+
+#ifndef __USE_POSIX2
#define __USE_POSIX2
+#endif /* __USE_POSIX2 */
#include <stdlib.h>
diff --git a/contrib/libpam/modules/pam_rhosts/Makefile b/contrib/libpam/modules/pam_rhosts/Makefile
index 93addbb68119..d12e00c0680e 100644
--- a/contrib/libpam/modules/pam_rhosts/Makefile
+++ b/contrib/libpam/modules/pam_rhosts/Makefile
@@ -1,94 +1,15 @@
-# This Makefile controls a build process of the pam_rhosts modules
-# for Linux-PAM. You should not modify this Makefile.
+#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
+#
-LIBAUTHOBJ = pam_rhosts_auth.o
-LIBAUTHSRC = pam_rhosts_auth.c
-LIBSESSOBJ =
-LIBSESSSRC =
-LIBPASSWDSRC =
-LIBPASSWDOBJ =
-LIBOBJ = $(LIBAUTHOBJ) $(LIBSESSOBJ) $(LIBPASSWDOBJ)
-LIBSRC = $(LIBAUTHSRC) $(LIBSESSSRC) $(LIBPASSWDSRC)
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = libpam_rhosts.o
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-endif
+TITLE=pam_rhosts_auth
-ifdef DYNAMIC
-LIBSESSSH =
-LIBAUTHSH = pam_rhosts_auth.so
-LIBPASSWDSH =
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBSHARED = $(LIBSESSSH) $(LIBAUTHSH) $(LIBPASSWDSH)
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; \
- ./register_static pam_rhosts_auth pam_rhosts/libpam_rhosts.o )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-endif
-
-ifdef DYNAMIC
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-endif
-
-ifdef STATIC
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-
-endif
-
-#.c.o:
-# $(CC) -c $(CFLAGS) $<
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-# tidy up
-
-remove:
- cd $(FAKEROOT)$(SECUREDIR) && rm -f $(LIBSHARED)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) a.out core *~
-
-extraclean:
- rm -f *.a *.out *.o *.so *.bak dynamic/* static/*
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
index 10dfcf797119..b633a52989d7 100644
--- a/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
+++ b/contrib/libpam/modules/pam_rhosts/pam_rhosts_auth.c
@@ -46,6 +46,10 @@
#include <endian.h>
#endif
+#ifdef NEED_FSUID_H
+#include <sys/fsuid.h>
+#endif /* NEED_FSUID_H */
+
#include <sys/types.h>
#include <sys/uio.h>
#include <string.h>
@@ -103,6 +107,7 @@ int innetgr(const char *, const char *, const char *,const char *);
struct _options {
int opt_no_hosts_equiv;
+ int opt_hosts_equiv_rootok;
int opt_no_rhosts;
int opt_debug;
int opt_nowarn;
@@ -111,6 +116,8 @@ struct _options {
int opt_promiscuous;
int opt_suppress;
int opt_private_group;
+ int opt_no_uid_check;
+ const char *superuser;
const char *last_error;
};
@@ -133,6 +140,11 @@ static void set_option (struct _options *opts, const char *arg)
return;
}
+ if (strcmp(arg, "hosts_equiv_rootok") == 0) {
+ opts->opt_hosts_equiv_rootok = 1;
+ return;
+ }
+
if (strcmp(arg, "no_rhosts") == 0) {
opts->opt_no_rhosts = 1;
return;
@@ -165,6 +177,15 @@ static void set_option (struct _options *opts, const char *arg)
return;
}
+ if (strcmp(arg, "no_uid_check") == 0) {
+ opts->opt_no_uid_check = 1; /* NIS optimization */
+ return;
+ }
+
+ if (strcmp(arg, "superuser=") == 0) {
+ opts->superuser = arg+sizeof("superuser=")-1;
+ return;
+ }
/*
* All other options are ignored at the present time.
*/
@@ -444,7 +465,7 @@ pam_iruserok(pam_handle_t *pamh,
int answer;
char pbuf[MAXPATHLEN]; /* potential buffer overrun */
- if ( !superuser && !opts->opt_no_hosts_equiv ) {
+ if ((!superuser||opts->opt_hosts_equiv_rootok) && !opts->opt_no_hosts_equiv ) {
/* try to open system hosts.equiv file */
hostf = fopen (_PATH_HEQUIV, "r");
@@ -677,8 +698,12 @@ static int _pam_auth_rhosts (pam_handle_t *pamh,
break;
}
+ if (opts.superuser && !strcmp(opts.superuser, luser)) {
+ as_root = 1;
+ }
+
/* check if the luser uid == 0... --cristiang */
- {
+ if (! opts.opt_no_uid_check) {
struct passwd *luser_pwd;
luser_pwd = getpwnam(luser);
@@ -759,30 +784,3 @@ struct pam_module _pam_rhosts_auth_modstruct = {
};
#endif
-
-/*
- * $Log: pam_rhosts_auth.c,v $
- * Revision 1.12 1997/09/27 14:34:01 morgan
- * fixed comment and renamed iruserok to pam_iruserok.
- *
- * Revision 1.11 1997/04/05 06:26:39 morgan
- * fairly major fixes and enhancements (see CHANGELOG for 0.57 release)
- *
- * Revision 1.10 1997/02/09 02:09:30 morgan
- * - implementation of 'debug' argument (Cristian Gafton)
- * - we check for uid=0 accounts instead of hardcoded 'root' (Cristian Gafton)
- *
- * Revision 1.9 1996/12/01 03:09:47 morgan
- * *** empty log message ***
- *
- * Revision 1.8 1996/11/12 06:08:59 morgan
- * Oliver Crow's "rootok" patch plus a little clean up of set_option
- * (AGM)
- *
- * Revision 1.7 1996/11/10 20:15:56 morgan
- * cross platform support
- *
- * Revision 1.6 1996/08/09 05:46:29 morgan
- * removed code for manually setting the remote username etc..
- *
- */
diff --git a/contrib/libpam/modules/pam_rootok/Makefile b/contrib/libpam/modules/pam_rootok/Makefile
index b37870801193..b908b1157ac2 100644
--- a/contrib/libpam/modules/pam_rootok/Makefile
+++ b/contrib/libpam/modules/pam_rootok/Makefile
@@ -1,111 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:25:20 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:25:20 morgan
-# fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.6 1997/02/15 19:15:50 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:16:10 morgan
-# cross platform support
-#
-# Revision 1.4 1996/09/05 06:29:36 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:47:46 morgan
-# make dynamic/static dirs!
-#
-# Revision 1.2 1996/05/26 04:04:53 morgan
-# automated static support
-#
-# Revision 1.1 1996/05/05 17:14:15 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/5/5
-#
-
-TITLE=pam_rootok
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_rootok
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_rootok/README b/contrib/libpam/modules/pam_rootok/README
index d7010dd9738d..eee59ff02b0c 100644
--- a/contrib/libpam/modules/pam_rootok/README
+++ b/contrib/libpam/modules/pam_rootok/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/05/10 04:15:31 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:56 agmorgan Exp $
#
this module is an authentication module that performs one task: if the
diff --git a/contrib/libpam/modules/pam_rootok/pam_rootok.c b/contrib/libpam/modules/pam_rootok/pam_rootok.c
index 21327d42e5ea..54795e3c2b3d 100644
--- a/contrib/libpam/modules/pam_rootok/pam_rootok.c
+++ b/contrib/libpam/modules/pam_rootok/pam_rootok.c
@@ -1,22 +1,13 @@
/* pam_rootok module */
/*
- * $Id: pam_rootok.c,v 1.5 1997/02/15 17:32:47 morgan Exp $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_rootok.c,v $
- * Revision 1.5 1997/02/15 17:32:47 morgan
- * removed fixed syslog buffer
- *
- * Revision 1.4 1996/12/01 03:10:14 morgan
- * reformatted
- *
- * Revision 1.3 1996/06/02 08:11:01 morgan
- * updated for new static protocol
+ * $Id: pam_rootok.c,v 1.1.1.1 2000/06/20 22:11:56 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*/
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
diff --git a/contrib/libpam/modules/pam_securetty/Makefile b/contrib/libpam/modules/pam_securetty/Makefile
index d8a09ea13377..8ac853c595ff 100644
--- a/contrib/libpam/modules/pam_securetty/Makefile
+++ b/contrib/libpam/modules/pam_securetty/Makefile
@@ -1,83 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_securetty
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
+TITLE=pam_securetty
-.c.o:
- $(CC) $(CFLAGS) -c $<
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_securetty/pam_securetty.c b/contrib/libpam/modules/pam_securetty/pam_securetty.c
index 369fb03dd060..9e6121e8be97 100644
--- a/contrib/libpam/modules/pam_securetty/pam_securetty.c
+++ b/contrib/libpam/modules/pam_securetty/pam_securetty.c
@@ -8,18 +8,10 @@
* July 25, 1996.
* This code shamelessly ripped from the pam_rootok module.
* Slight modifications AGM. 1996/12/3
- * $Log: pam_securetty.c,v $
- * Revision 1.7 1997/04/05 06:24:23 morgan
- * changed return value on user unknown error
- *
- * Revision 1.6 1997/02/15 17:30:36 morgan
- * removed fixed length syslog buffer
- *
- * Revision 1.5 1997/02/09 02:22:24 morgan
- * added "debug" flag handling (Cristian Gafton)
- *
*/
+#define _GNU_SOURCE
+
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
@@ -28,7 +20,7 @@
#include <syslog.h>
#include <stdarg.h>
#include <pwd.h>
-#include <strings.h>
+#include <string.h>
#define PAM_SM_AUTH
@@ -97,13 +89,20 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
/* parse the arguments */
ctrl = _pam_parse(argc, argv);
- retval = pam_get_item(pamh,PAM_USER,(const void **)&username);
- if (retval == PAM_SUCCESS)
- retval = pam_get_item(pamh,PAM_TTY,(const void **)&uttyname);
+ retval = pam_get_user(pamh, &username, NULL);
+ if (retval != PAM_SUCCESS || username == NULL) {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine username");
+ }
+ return (retval == PAM_CONV_AGAIN
+ ? PAM_INCOMPLETE:PAM_SERVICE_ERR);
+ }
+
+ retval = pam_get_item(pamh, PAM_TTY, (const void **)&uttyname);
if (retval != PAM_SUCCESS || uttyname == NULL) {
- /* If we couldn't get the username or the tty return error */
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_WARNING, "can not determine tty I'm running on !");
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_WARNING, "cannot determine user's tty");
+ }
return PAM_SERVICE_ERR;
}
@@ -111,36 +110,24 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
if (strncmp(TTY_PREFIX, uttyname, sizeof(TTY_PREFIX)-1) == 0)
uttyname += sizeof(TTY_PREFIX)-1;
- /* If we didn't get a username, get one */
- if(!username || (strlen(username) <= 0)) {
- /* Don't let them use a NULL username... */
- (void) pam_set_item(pamh, PAM_USER, NULL);
- pam_get_user(pamh,&username,NULL);
- if (retval != PAM_SUCCESS || username == NULL || *username == '\0') {
- if (ctrl & PAM_DEBUG_ARG)
- _pam_log(LOG_WARNING,
- "can not determine username for this service!");
- return PAM_SERVICE_ERR;
- }
- }
-
user_pwd = getpwnam(username);
- if (user_pwd == NULL)
+ if (user_pwd == NULL) {
return PAM_IGNORE;
- else if (user_pwd->pw_uid != 0) /* If the user is not root,
- securetty's does not apply to them */
+ } else if (user_pwd->pw_uid != 0) { /* If the user is not root,
+ securetty's does not apply
+ to them */
return PAM_SUCCESS;
+ }
- if(stat(SECURETTY_FILE,&ttyfileinfo)) {
- _pam_log(LOG_NOTICE,
- "Couldn't open " SECURETTY_FILE);
+ if (stat(SECURETTY_FILE, &ttyfileinfo)) {
+ _pam_log(LOG_NOTICE, "Couldn't open " SECURETTY_FILE);
return PAM_SUCCESS; /* for compatibility with old securetty handling,
this needs to succeed. But we still log the
error. */
}
- if((ttyfileinfo.st_mode & S_IWOTH)
- || !S_ISREG(ttyfileinfo.st_mode)) {
+ if ((ttyfileinfo.st_mode & S_IWOTH)
+ || !S_ISREG(ttyfileinfo.st_mode)) {
/* If the file is world writable or is not a
normal file, return error */
_pam_log(LOG_ERR, SECURETTY_FILE
diff --git a/contrib/libpam/modules/pam_shells/Makefile b/contrib/libpam/modules/pam_shells/Makefile
index 121b19a00863..f1d7ff515187 100644
--- a/contrib/libpam/modules/pam_shells/Makefile
+++ b/contrib/libpam/modules/pam_shells/Makefile
@@ -1,84 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-
-TITLE=pam_shells
-
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+include ../../Make.Rules
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_shells
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_shells/pam_shells.c b/contrib/libpam/modules/pam_shells/pam_shells.c
index edc9134b3274..36dd1a917e4e 100644
--- a/contrib/libpam/modules/pam_shells/pam_shells.c
+++ b/contrib/libpam/modules/pam_shells/pam_shells.c
@@ -1,4 +1,4 @@
-/* pam_securetty module */
+/* pam_shells module */
#define SHELL_FILE "/etc/shells"
@@ -8,6 +8,8 @@
* This code shamelessly ripped from the pam_securetty module.
*/
+#define _BSD_SOURCE
+
#include <pwd.h>
#include <stdarg.h>
#include <stdio.h>
@@ -71,21 +73,21 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
userShell = pw->pw_shell;
if(stat(SHELL_FILE,&sb)) {
- _pam_log(LOG_ERR, SHELL_FILE, " cannot be stat'd (it probably does "
- "not exist)");
+ _pam_log(LOG_ERR,
+ "%s cannot be stat'd (it probably does not exist)", SHELL_FILE);
return PAM_AUTH_ERR; /* must have /etc/shells */
}
if((sb.st_mode & S_IWOTH) || !S_ISREG(sb.st_mode)) {
- _pam_log(LOG_ERR,
- SHELL_FILE " is either world writable or not a normal file");
- return PAM_AUTH_ERR;
+ _pam_log(LOG_ERR,
+ "%s is either world writable or not a normal file", SHELL_FILE);
+ return PAM_AUTH_ERR;
}
shellFile = fopen(SHELL_FILE,"r");
if(shellFile == NULL) { /* Check that we opened it successfully */
- _pam_log(LOG_ERR,
- "Error opening " SHELL_FILE);
+ _pam_log(LOG_ERR,
+ "Error opening %s", SHELL_FILE);
return PAM_SERVICE_ERR;
}
/* There should be no more errors from here on */
diff --git a/contrib/libpam/modules/pam_stress/Makefile b/contrib/libpam/modules/pam_stress/Makefile
index 52e8e21881a3..3512c853aef9 100644
--- a/contrib/libpam/modules/pam_stress/Makefile
+++ b/contrib/libpam/modules/pam_stress/Makefile
@@ -1,109 +1,15 @@
#
-# $Id: Makefile,v 1.7 1997/04/05 06:23:08 morgan Exp $
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/3/11
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.7 1997/04/05 06:23:08 morgan
-# fakeroot
-#
-# Revision 1.6 1997/02/15 19:05:55 morgan
-# fixed email
-#
-# Revision 1.5 1996/11/10 20:17:55 morgan
-# cross platform support
-#
-# Revision 1.4 1996/09/05 06:31:09 morgan
-# ld --> gcc
-#
-# Revision 1.3 1996/05/26 15:50:43 morgan
-# make dynamic and static dirs
-#
-# Revision 1.2 1996/05/26 04:11:56 morgan
-# automated static support
-#
-#
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-TITLE=pam_stress
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
+include ../../Make.Rules
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_stress
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_stress/README b/contrib/libpam/modules/pam_stress/README
index 1cb7c14b73c3..b4273f501ff4 100644
--- a/contrib/libpam/modules/pam_stress/README
+++ b/contrib/libpam/modules/pam_stress/README
@@ -1,5 +1,5 @@
#
-# $Id: README,v 1.7 1997/02/15 19:07:08 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:11:57 agmorgan Exp $
#
# This describes the behavior of this module with respect to the
# /etc/pam.conf file.
diff --git a/contrib/libpam/modules/pam_stress/pam_stress.c b/contrib/libpam/modules/pam_stress/pam_stress.c
index 501541850461..52d9e8041ec8 100644
--- a/contrib/libpam/modules/pam_stress/pam_stress.c
+++ b/contrib/libpam/modules/pam_stress/pam_stress.c
@@ -1,34 +1,18 @@
/* pam_stress module */
-/* $Id: pam_stress.c,v 1.12 1997/02/15 19:06:30 morgan Exp morgan $
- *
- * created by Andrew Morgan <morgan@parc.power.net> 1996/3/12
- *
- * $Log: pam_stress.c,v $
- * Revision 1.12 1997/02/15 19:06:30 morgan
- * fixed email
- *
- * Revision 1.11 1997/02/15 17:33:24 morgan
- * removed fixed syslog buffer
- *
- * Revision 1.10 1996/12/01 03:11:35 morgan
- * using _pam_macros.h now
- *
- * Revision 1.9 1996/11/10 20:18:10 morgan
- * changes for .53 compilation
- *
- * Revision 1.8 1996/09/05 06:31:59 morgan
- * changed return value of wipe_up from int to void
- *
- * Revision 1.7 1996/06/02 08:12:28 morgan
- * updated for new static protocol, added STRESS to various user prompts
- * and added rootok flag for pam_sm_chauthtok to look out for
+/* $Id: pam_stress.c,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
*
+ * created by Andrew Morgan <morgan@linux.kernel.org> 1996/3/12
*/
+#include <security/_pam_aconf.h>
+
#include <stdlib.h>
#include <stdio.h>
+
+#define __USE_BSD
#include <syslog.h>
+
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
diff --git a/contrib/libpam/modules/pam_tally/Makefile b/contrib/libpam/modules/pam_tally/Makefile
index ec17ff31fa8e..032b93416bd9 100644
--- a/contrib/libpam/modules/pam_tally/Makefile
+++ b/contrib/libpam/modules/pam_tally/Makefile
@@ -1,20 +1,19 @@
#
-# $Id: Makefile,v 1.1 1997/04/05 06:19:04 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
-# This Makefile controls a build process of $(TITLE) module for
-# Linux-PAM. You should not modify this Makefile (unless you know
-# what you are doing!).
-#
-# $Log: Makefile,v $
-# Revision 1.1 1997/04/05 06:19:04 morgan
-# Initial revision
+# This Makefile controls a build process of $(TITLE) module and
+# application for Linux-PAM. You should not modify this Makefile
+# (unless you know what you are doing!).
#
#
+include ../../Make.Rules
+
TITLE=pam_tally
#
-## Should add some more rules to make the application too.
+## Additional rules for making (and moving) the application added.
+## Assuming that all modules' applications are called $TITLE
#
LIBSRC = $(TITLE).c
@@ -22,6 +21,11 @@ LIBOBJ = $(TITLE).o
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBOBJS = $(addprefix static/,$(LIBOBJ))
+APPSRC = $(TITLE)_app.c
+APPOBJ = $(TITLE)_app.o
+APPOBJD = $(addprefix dynamic/,$(APPOBJ))
+APPOBJS = $(addprefix static/,$(APPOBJ))
+
dynamic/%.o : %.c
$(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
@@ -37,14 +41,12 @@ ifdef STATIC
LIBSTATIC = lib$(TITLE).o
endif
-####################### don't edit below #######################
+APPLICATION = $(TITLE)
+APPMODE = 755
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
+####################### don't edit below #######################
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
+all: dirs $(LIBSHARED) $(LIBSTATIC) register $(APPLICATION)
dirs:
ifdef DYNAMIC
@@ -62,8 +64,12 @@ endif
ifdef DYNAMIC
$(LIBOBJD): $(LIBSRC)
-$(LIBSHARED): $(LIBOBJD)
+$(LIBSHARED): $(LIBOBJD)
$(LD_D) -o $@ $(LIBOBJD)
+
+$(APPLICATION): $(APPOBJD)
+ $(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
+
endif
ifdef STATIC
@@ -71,6 +77,9 @@ $(LIBOBJS): $(LIBSRC)
$(LIBSTATIC): $(LIBOBJS)
$(LD) -r -o $@ $(LIBOBJS)
+
+$(APPLICATION): $(APPOBJS)
+ $(CC) $(CFLAGS) -o $@ $< $(LOADLIBES)
endif
install: all
@@ -78,16 +87,17 @@ install: all
ifdef DYNAMIC
$(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
endif
+ $(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
+# $(INSTALL) -m $(APPMODE) $(APPLICATION) $(FAKEROOT)$(SUPLEMENTED)
remove:
rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
+ rm -f $(FAKEROOT)$(SUPLEMENTED)/$(TITLE)
clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
+ rm -f $(LIBOBJD) $(LIBOBJS) $(APPOBJD) $(APPOBJS) core *~
+ rm -f *.a *.o *.so *.bak dynamic/* static/* $(APPLICATION)
+ rm -rf dynamic static
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
+.c.o:
$(CC) $(CFLAGS) -c $<
-
diff --git a/contrib/libpam/modules/pam_tally/README b/contrib/libpam/modules/pam_tally/README
index aaa8512bade4..b58b24e45793 100644
--- a/contrib/libpam/modules/pam_tally/README
+++ b/contrib/libpam/modules/pam_tally/README
@@ -1,4 +1,3 @@
-
SUMMARY:
pam_tally:
@@ -12,10 +11,12 @@ SUMMARY:
* file=/where/to/keep/counts (default /var/log/faillog)
(auth)
+ Authentication phase increments attempted login counter.
* no_magic_root (root DOES increment counter. Use for
daemon-based stuff, like telnet/rsh/login)
(account)
+ Account phase can deny access and/or reset attempts counter.
* deny=n (deny access if tally for this user exceeds n;
The presence of deny=n changes the default for
reset/no_reset to reset, unless the user trying to
@@ -34,11 +35,54 @@ SUMMARY:
This is the default unless deny exists and the
user attempting access is NOT magic root.
- Also checks to make sure that the list file is a plain
+ * per_user (If /var/log/faillog contains a non-zero
+ .fail_max field for this user then use it
+ instead of deny=n parameter)
+
+ * no_lock_time (Don't use .fail_locktime filed in
+ /var/log/faillog for this user)
+
+ Also checks to make sure that the counts file is a plain
file and not world writable.
- - Tim Baverstock <warwick@mmm.co.uk>, Multi Media Machine Ltd.
- v0.1 5 March 1997
+ - Tim Baverstock <warwick@sable.demon.co.uk>, v0.1 5 March 1997
+
+LONGER:
+
+pam_tally comes in two parts: pam_tally.so and pam_tally.
+
+pam_tally.so sits in a pam config file, in the auth and account sections.
+
+In the auth section, it increments a per-uid counter for each attempted
+login, in the account section, it denies access if attempted logins
+exceed some threashold and/or resets that counter to zero on successful
+login.
+
+Root is treated specially:
+
+1. When a process already running as root tries to access some service, the
+access is `magic', and bypasses pam_tally's checks: handy for `su'ing from
+root into an account otherwise blocked. However, for services like telnet or
+login 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. [This option may
+be obsolete, with `sufficient root' processing.]
+
+2. Normally, failed attempts to access root will NOT cause the root
+account to become blocked, to prevent denial-of-service: if your users aren't
+given shell accounts and root may only login via `su' or at the machine
+console (not telnet/rsh, etc), this is safe. If you really want root to be
+blocked for some given service, use even_deny_root_account.
+
+pam_tally 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. I found it useful to
+clear all counts every midnight from a cron..
+
+The counts file is organised as a binary-word array, indexed by uid. You
+can probably make sense of it with `od', if you don't want to use the
+supplied appliction.
BUGS:
diff --git a/contrib/libpam/modules/pam_tally/faillog.h b/contrib/libpam/modules/pam_tally/faillog.h
new file mode 100644
index 000000000000..0f16261bbd9c
--- /dev/null
+++ b/contrib/libpam/modules/pam_tally/faillog.h
@@ -0,0 +1,55 @@
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``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 JULIE HAUGH OR CONTRIBUTORS 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.
+ */
+
+/*
+ * faillog.h - login failure logging file format
+ *
+ * $Id: faillog.h,v 1.1.1.1 2000/06/20 22:11:59 agmorgan Exp $
+ *
+ * The login failure file is maintained by login(1) and faillog(8)
+ * Each record in the file represents a separate UID and the file
+ * is indexed in that fashion.
+ */
+
+#ifndef _FAILLOG_H
+#define _FAILLOG_H
+
+struct faillog {
+ short fail_cnt; /* failures since last success */
+ short fail_max; /* failures before turning account off */
+ char fail_line[12]; /* last failure occured here */
+ time_t fail_time; /* last failure occured then */
+ /*
+ * If nonzero, the account will be re-enabled if there are no
+ * failures for fail_locktime seconds since last failure.
+ */
+ long fail_locktime;
+};
+
+#endif
diff --git a/contrib/libpam/modules/pam_tally/pam_tally.c b/contrib/libpam/modules/pam_tally/pam_tally.c
index a1b65c04e958..23067f794e6a 100644
--- a/contrib/libpam/modules/pam_tally/pam_tally.c
+++ b/contrib/libpam/modules/pam_tally/pam_tally.c
@@ -1,7 +1,7 @@
/*
* pam_tally.c
*
- * Revision history? :) 0.1
+ * $Id: pam_tally.c,v 1.5 2001/01/20 22:21:22 agmorgan Exp $
*/
@@ -11,21 +11,20 @@
* Stuff stolen from pam_rootok and pam_listfile
*/
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdio.h>
-#include <strings.h>
+#include <string.h>
#include <unistd.h>
#include <stdarg.h>
#include <syslog.h>
#include <pwd.h>
+#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
+#include "faillog.h"
#ifndef TRUE
#define TRUE 1L
@@ -67,6 +66,13 @@ enum TALLY_RESET {
# define FILENAME_MAX MAXPATHLEN
#endif
+struct fail_s {
+ struct faillog fs_faillog;
+#ifndef MAIN
+ time_t fs_fail_time;
+#endif /* ndef MAIN */
+};
+
/*---------------------------------------------------------------------*/
/* some syslogging */
@@ -131,19 +137,23 @@ static int pam_get_uid( pam_handle_t *pamh, uid_t *uid, const char **userp )
static int get_tally( tally_t *tally,
uid_t uid,
const char *filename,
- FILE **TALLY )
+ FILE **TALLY,
+ struct fail_s *fsp)
{
struct stat fileinfo;
int lstat_ret = lstat(filename,&fileinfo);
if ( lstat_ret && *tally!=TALLY_HI ) {
- if ( ( *TALLY=fopen(filename, "a") ) ) {
- /* Create file, or append-open in pathological case. */
+ int oldmask = umask(077);
+ *TALLY=fopen(filename, "a");
+ /* Create file, or append-open in pathological case. */
+ umask(oldmask);
+ if ( !*TALLY ) {
_pam_log(LOG_ALERT, "Couldn't create %s",filename);
return PAM_AUTH_ERR;
}
+ lstat_ret = fstat(fileno(*TALLY),&fileinfo);
fclose(*TALLY);
- lstat_ret = lstat(filename,&fileinfo);
}
if ( lstat_ret ) {
@@ -171,14 +181,18 @@ static int get_tally( tally_t *tally,
return PAM_AUTH_ERR;
}
- if ( fseek( *TALLY, uid * sizeof (tally_t), SEEK_SET ) ) {
- _pam_log(LOG_ALERT, "fseek failed %s", filename);
- return PAM_AUTH_ERR;
- }
-
- if ( ( fread(tally, sizeof(tally_t), 1, *TALLY) )==0 ) {
- *tally=0; /* Assuming a gappy filesystem */
+ if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) {
+ _pam_log(LOG_ALERT, "fseek failed %s", filename);
+ return PAM_AUTH_ERR;
+ }
+
+
+ if (( fread((char *) &fsp->fs_faillog,
+ sizeof(struct faillog), 1, *TALLY) )==0 ) {
+ *tally=0; /* Assuming a gappy filesystem */
}
+ *tally = fsp->fs_faillog.fail_cnt;
+
return PAM_SUCCESS;
}
@@ -189,16 +203,18 @@ static int get_tally( tally_t *tally,
static int set_tally( tally_t tally,
uid_t uid,
const char *filename,
- FILE **TALLY )
+ FILE **TALLY,
+ struct fail_s *fsp)
{
if ( tally!=TALLY_HI )
{
- if ( fseek( *TALLY, uid * sizeof(tally_t), SEEK_SET ) ) {
- _pam_log(LOG_ALERT, "fseek failed %s", filename);
- return PAM_AUTH_ERR;
+ if ( fseek( *TALLY, uid * sizeof(struct faillog), SEEK_SET ) ) {
+ _pam_log(LOG_ALERT, "fseek failed %s", filename);
+ return PAM_AUTH_ERR;
}
-
- if ( fwrite(&tally, sizeof(tally_t), 1, *TALLY)==0 ) {
+ fsp->fs_faillog.fail_cnt = tally;
+ if (fwrite((char *) &fsp->fs_faillog,
+ sizeof(struct faillog), 1, *TALLY)==0 ) {
_pam_log(LOG_ALERT, "tally update (fputc) failed.", filename);
return PAM_AUTH_ERR;
}
@@ -284,12 +300,37 @@ static int tally_bump (int inc,
FILE
*TALLY = NULL;
const char
- *user = NULL;
+ *user = NULL,
+ *remote_host = NULL,
+ *cur_tty = NULL;
+ struct fail_s fs, *fsp = &fs;
int i=pam_get_uid(pamh, &uid, &user);
if ( i != PAM_SUCCESS ) RETURN_ERROR( i );
- i=get_tally( &tally, uid, filename, &TALLY );
+ i=get_tally( &tally, uid, filename, &TALLY, fsp );
+
+ /* to remember old fail time (for locktime) */
+ fsp->fs_fail_time = fsp->fs_faillog.fail_time;
+ fsp->fs_faillog.fail_time = (time_t) time( (time_t *) 0);
+ (void) pam_get_item(pamh, PAM_RHOST, (const void **)&remote_host);
+ if (!remote_host)
+ {
+ (void) pam_get_item(pamh, PAM_TTY, (const void **)&cur_tty);
+ if (!cur_tty)
+ strcpy(fsp->fs_faillog.fail_line, "unknown");
+ else {
+ strncpy(fsp->fs_faillog.fail_line, cur_tty,
+ (size_t)sizeof(fsp->fs_faillog.fail_line));
+ fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0;
+ }
+ }
+ else
+ {
+ strncpy(fsp->fs_faillog.fail_line, remote_host,
+ (size_t)sizeof(fsp->fs_faillog.fail_line));
+ fsp->fs_faillog.fail_line[sizeof(fsp->fs_faillog.fail_line)-1] = 0;
+ }
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
if ( no_magic_root || getuid() ) { /* no_magic_root kills uid test */
@@ -303,7 +344,7 @@ static int tally_bump (int inc,
}
}
- i=set_tally( tally, uid, filename, &TALLY );
+ i=set_tally( tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
}
@@ -370,6 +411,8 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
char
no_magic_root = FALSE,
even_deny_root_account = FALSE;
+ char per_user = FALSE; /* if true then deny=.fail_max for user */
+ char no_lock_time = FALSE; /* if true then don't use .fail_locktime */
const char
*user = NULL;
@@ -424,6 +467,14 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
else if ( ! strcmp( *argv, "onerr=succeed" ) ) {
fail_on_error=FALSE;
}
+ else if ( ! strcmp( *argv, "per_user" ) )
+ {
+ per_user = TRUE;
+ }
+ else if ( ! strcmp( *argv, "no_lock_time") )
+ {
+ no_lock_time = TRUE;
+ }
else {
_pam_log(LOG_ERR, MODULE_NAME ": unknown option; %s",*argv);
}
@@ -431,17 +482,38 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
}
{
+ struct fail_s fs, *fsp = &fs;
FILE *TALLY=0;
int i=pam_get_uid(pamh, &uid, &user);
if ( i != PAM_SUCCESS ) RETURN_ERROR( i );
- i=get_tally( &tally, uid, filename, &TALLY );
+ i=get_tally( &tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
if ( no_magic_root || getuid() ) { /* no_magic_root kills uid test */
/* To deny or not to deny; that is the question */
+ /* if there's .fail_max entry and per_user=TRUE then deny=.fail_max */
+
+ if ( (fsp->fs_faillog.fail_max) && (per_user) ) {
+ deny = fsp->fs_faillog.fail_max;
+ }
+ if (fsp->fs_faillog.fail_locktime && fsp->fs_fail_time
+ && (!no_lock_time) )
+ {
+ if ( (fsp->fs_faillog.fail_locktime + fsp->fs_fail_time)
+ > (time_t)time((time_t)0) )
+ {
+ _pam_log(LOG_NOTICE,
+ "user %s ("UID_FMT") has time limit [%lds left]"
+ " since last failure.",
+ user,uid,
+ fsp->fs_fail_time+fsp->fs_faillog.fail_locktime
+ -(time_t)time((time_t)0));
+ return PAM_AUTH_ERR;
+ }
+ }
if (
( deny != 0 ) && /* deny==0 means no deny */
( tally > deny ) && /* tally>deny means exceeded */
@@ -467,8 +539,12 @@ PAM_FUNCTION( pam_sm_acct_mgmt ) {
if ( reset == TALLY_RESET_RESET ) { tally=0; }
}
-
- i=set_tally( tally, uid, filename, &TALLY );
+ if (tally == 0)
+ {
+ fsp->fs_faillog.fail_time = (time_t) 0;
+ strcpy(fsp->fs_faillog.fail_line, "");
+ }
+ i=set_tally( tally, uid, filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) { if (TALLY) fclose(TALLY); RETURN_ERROR( i ); }
}
@@ -557,6 +633,8 @@ static int getopts( int argc, char **argv ) {
int main ( int argc, char **argv ) {
+ struct fail_s fs, *fsp = &fs;
+
if ( ! getopts( argc, argv+1 ) ) {
printf("%s: [--file rooted-filename] [--user username] "
"[--reset[=n]] [--quiet]\n",
@@ -564,6 +642,8 @@ int main ( int argc, char **argv ) {
exit(0);
}
+ umask(077);
+
/*
* Major difference between individual user and all users:
* --user just handles one user, just like PAM.
@@ -580,7 +660,7 @@ int main ( int argc, char **argv ) {
exit(0);
}
- i=get_tally( &tally, uid, cline_filename, &TALLY );
+ i=get_tally( &tally, uid, cline_filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) {
if (TALLY) fclose(TALLY);
fprintf(stderr,"%s: %s\n",*argv,pam_errors(i));
@@ -591,7 +671,7 @@ int main ( int argc, char **argv ) {
printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",cline_user,uid,
(cline_reset!=TALLY_HI)?"had":"has",tally);
- i=set_tally( cline_reset, uid, cline_filename, &TALLY );
+ i=set_tally( cline_reset, uid, cline_filename, &TALLY, fsp );
if ( i != PAM_SUCCESS ) {
if (TALLY) fclose(TALLY);
fprintf(stderr,"%s: %s\n",*argv,pam_errors(i));
@@ -606,7 +686,13 @@ int main ( int argc, char **argv ) {
for ( ; !feof(TALLY); uid++ ) {
tally_t tally;
struct passwd *pw;
- if ( ! fread(&tally, sizeof(tally_t), 1, TALLY) || ! tally ) continue;
+ if ( ! fread((char *) &fsp->fs_faillog,
+ sizeof (struct faillog), 1, TALLY)
+ || ! fsp->fs_faillog.fail_cnt ) {
+ tally=fsp->fs_faillog.fail_cnt;
+ continue;
+ }
+ tally = fsp->fs_faillog.fail_cnt;
if ( ( pw=getpwuid(uid) ) ) {
printf("User %s\t("UID_FMT")\t%s "TALLY_FMT"\n",pw->pw_name,uid,
diff --git a/contrib/libpam/modules/pam_tally/pam_tally_app.c b/contrib/libpam/modules/pam_tally/pam_tally_app.c
new file mode 100644
index 000000000000..9e6e1fafd062
--- /dev/null
+++ b/contrib/libpam/modules/pam_tally/pam_tally_app.c
@@ -0,0 +1,7 @@
+/*
+ # This seemed like such a good idea at the time. :)
+ */
+
+#define MAIN
+#include "pam_tally.c"
+
diff --git a/contrib/libpam/modules/pam_time/Makefile b/contrib/libpam/modules/pam_time/Makefile
index bc297d4f9853..4aa4e2761ee0 100644
--- a/contrib/libpam/modules/pam_time/Makefile
+++ b/contrib/libpam/modules/pam_time/Makefile
@@ -1,121 +1,21 @@
-#
-# $Id: Makefile,v 1.6 1997/04/05 06:22:32 morgan Exp morgan $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:05 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.6 1997/04/05 06:22:32 morgan
-# fakeroot
-#
-# Revision 1.5 1997/02/15 19:16:16 morgan
-# fixed email
-#
-# Revision 1.4 1996/11/10 20:18:21 morgan
-# cross platform support
-#
-# Revision 1.3 1996/09/05 06:27:37 morgan
-# ld --> gcc
-#
-# Revision 1.2 1996/08/09 05:48:19 morgan
-# inherit installation files from parent
-#
-# Revision 1.1 1996/07/07 23:42:48 morgan
-# Initial revision
-#
-# Revision 1.1 1996/06/24 05:48:49 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/6/11
-#
-
-TITLE=pam_time
-CONFD=$(CONFIGED)/security
-export CONFD
-CONFILE=$(CONFD)/time.conf
-export CONFILE
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
+include ../../Make.Rules
-DEFS=-DCONFILE=\"$(CONFILE)\"
+TITLE=pam_time
+LOCAL_CONFILE=./time.conf
+INSTALLED_CONFILE=$(SCONFIGD)/time.conf
+DEFS=-DDEFAULT_CONF_FILE=\"$(INSTALLED_CONFILE)\"
CFLAGS += $(DEFS)
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-
-dummy:
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
-ifdef DYNAMIC
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
- $(MKDIR) $(FAKEROOT)$(SCONFIGED)
- bash -f ./install_conf
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
- rm -f $(FAKEROOT)$(CONFILE)
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
- rm -f ./.ignore_age
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+MODULE_SIMPLE_INSTALL=bash -f ../install_conf "$(FAKEROOT)" "$(SCONFIGD)" "$(INSTALLED_CONFILE)" "$(TITLE)" "$(LOCAL_CONFILE)"
+MODULE_SIMPLE_REMOVE=rm -f $(FAKEROOT)$(INSTALLED_CONFILE)
+MODULE_SIMPLE_CLEAN=rm -f ./.ignore_age
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_time/README b/contrib/libpam/modules/pam_time/README
index 0c3f976b4012..0228b907fc21 100644
--- a/contrib/libpam/modules/pam_time/README
+++ b/contrib/libpam/modules/pam_time/README
@@ -1,4 +1,4 @@
-$Id: README,v 1.3 1997/01/04 20:42:43 morgan Exp $
+$Id: README,v 1.2 2000/12/04 19:02:35 baggins Exp $
This is a help file for the pam_time module. It explains the need for
pam_time and also the syntax of the /etc/security/time.conf file.
@@ -28,10 +28,3 @@ unrecognised rules are ignored (but an error is logged to syslog(3))
--------------------
Bugs to Andrew <morgan@parc.power.net> or the list <pam-list@redhat.com>
-
-########################################################################
-# $Log: README,v $
-# Revision 1.3 1997/01/04 20:42:43 morgan
-# I want email on parc now
-#
-# \ No newline at end of file
diff --git a/contrib/libpam/modules/pam_time/pam_time.c b/contrib/libpam/modules/pam_time/pam_time.c
index 489c1d734ae0..a517abf0e3d2 100644
--- a/contrib/libpam/modules/pam_time/pam_time.c
+++ b/contrib/libpam/modules/pam_time/pam_time.c
@@ -1,25 +1,19 @@
/* pam_time module */
/*
- * $Id: pam_time.c,v 1.7 1997/02/15 17:32:21 morgan Exp $
+ * $Id: pam_time.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $
*
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/6/22
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/6/22
* (File syntax and much other inspiration from the shadow package
* shadow-960129)
- *
- * $Log: pam_time.c,v $
- * Revision 1.7 1997/02/15 17:32:21 morgan
- * time parsing more robust
- *
- * Revision 1.6 1997/01/04 20:43:15 morgan
- * fixed buffer underflow, reformatted to 4 spaces
- *
*/
const static char rcsid[] =
-"$Id: pam_time.c,v 1.7 1997/02/15 17:32:21 morgan Exp $;\n"
+"$Id: pam_time.c,v 1.3 2000/11/26 07:32:39 agmorgan Exp $;\n"
"\t\tVersion 0.22 for Linux-PAM\n"
-"Copyright (C) Andrew G. Morgan 1996 <morgan@parc.power.net>\n";
+"Copyright (C) Andrew G. Morgan 1996 <morgan@linux.kernel.org>\n";
+
+#include <security/_pam_aconf.h>
#include <sys/file.h>
#include <stdio.h>
@@ -34,7 +28,11 @@ const static char rcsid[] =
#include <sys/stat.h>
#include <fcntl.h>
-#define PAM_TIME_CONF CONFILE /* from external define */
+#ifdef DEFAULT_CONF_FILE
+# define PAM_TIME_CONF DEFAULT_CONF_FILE /* from external define */
+#else
+# define PAM_TIME_CONF "/etc/security/time.conf"
+#endif
#define PAM_TIME_BUFLEN 1000
#define FIELD_SEPARATOR ';' /* this is new as of .02 */
@@ -124,6 +122,7 @@ static int read_field(int fd, char **buf, int *from, int *to)
_log_err("error reading " PAM_TIME_CONF);
return -1;
} else if (!i) {
+ close(fd);
fd = -1; /* end of file reached */
} else
*to += i;
@@ -167,6 +166,8 @@ static int read_field(int fd, char **buf, int *from, int *to)
if ((*buf)[i+1] == '\n') {
shift_bytes(i + *buf, 2, *to - (i+2));
*to -= 2;
+ } else {
+ ++i; /* we don't escape non-newline characters */
}
break;
case '!':
@@ -248,7 +249,7 @@ static int logic_member(const char *string, int *at)
default:
if (isalpha(c) || c == '*' || isdigit(c) || c == '_'
- || c == '-' || c == '.') {
+ || c == '-' || c == '.' || c == '/') {
token = 1;
} else if (token) {
--to;
diff --git a/contrib/libpam/modules/pam_unix/CHANGELOG b/contrib/libpam/modules/pam_unix/CHANGELOG
index 37e4c8501c9d..509ce0a31a62 100644
--- a/contrib/libpam/modules/pam_unix/CHANGELOG
+++ b/contrib/libpam/modules/pam_unix/CHANGELOG
@@ -1,6 +1,55 @@
-$Id: CHANGELOG,v 1.1 1996/11/09 19:42:41 morgan Exp $
+$Id: CHANGELOG,v 1.1.1.1 2000/06/20 22:12:01 agmorgan Exp $
-$Log: CHANGELOG,v $
-Revision 1.1 1996/11/09 19:42:41 morgan
-Initial revision
+* Mon Aug 16 1999 Jan Rêkorajski <baggins@pld.org.pl>
+- fixed reentrancy problems
+
+* Sun Jul 4 21:03:42 PDT 1999
+
+- temporarily removed the crypt16 stuff. I'm really paranoid about
+ crypto stuff and exporting it, and there are a few too many 's-box'
+ references in the code for my liking..
+
+* Wed Jun 30 1999 Steve Langasek <vorlon@netexpress.net>
+- further NIS+ fixes
+
+* Sun Jun 27 1999 Steve Langasek <vorlon@netexpress.net>
+- fix to uid-handling code for NIS+
+
+* Sat Jun 26 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- merged MD5 fix and early failure syslog
+ by Andrey Vladimirovich Savochkin <saw@msu.ru>
+- minor fixes
+- added signal handler to unix_chkpwd
+
+* Fri Jun 25 1999 Stephen Langasek <vorlon@netexpress.net>
+- reorganized the code to let it build as separate C files
+
+* Sun Jun 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- fixes in pam_unix_auth, it incorrectly saved and restored return
+ value when likeauth option was used
+
+* Tue Jun 15 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added NIS+ support
+
+* Mon Jun 14 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- total rewrite based on pam_pwdb module, now there is ONE pam_unix.so
+ module, it accepts the same options as pam_pwdb - all of them correctly ;)
+ (pam_pwdb dosn't understand what DISALLOW_NULL_AUTHTOK means)
+
+* Tue Apr 20 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- Arghhh, pam_unix_passwd was not updating /etc/shadow when used with
+ pam_cracklib.
+
+* Mon Apr 19 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added "remember=XXX" option that means 'remember XXX old passwords'
+ Old passwords are stored in /etc/security/opasswd, there can be
+ maximum of 400 passwords per user.
+
+* Sat Mar 27 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- added crypt16 to pam_unix_auth and pam_unix_passwd (check only, this algorithm
+ is too lame to use it in real life)
+
+* Sun Mar 21 1999 Jan Rêkorajski <baggins@mimuw.edu.pl>
+- pam_unix_auth now correctly behave when user has NULL AUTHTOK
+- pam_unix_auth returns PAM_PERM_DENIED when seteuid fails
diff --git a/contrib/libpam/modules/pam_unix/Makefile b/contrib/libpam/modules/pam_unix/Makefile
index ad1f47f185e4..9329aa6e1006 100644
--- a/contrib/libpam/modules/pam_unix/Makefile
+++ b/contrib/libpam/modules/pam_unix/Makefile
@@ -1,100 +1,91 @@
-# $Header$
+# $Id: Makefile,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
#
# This Makefile controls a build process of the pam_unix modules
# for Linux-PAM. You should not modify this Makefile.
#
-# $Log$
-# Revision 1.1.1.2 1998/06/03 03:43:56 adam
-# Import from archive
-#
-# Revision 1.3 1998/05/31 23:48:13 adam
-# Link crypt library as necessary.
-#
-# Revision 1.3 1997/04/05 06:20:58 morgan
-# fakeroot and also lockpwdf is in libc now
-#
-# Revision 1.2 1996/11/10 20:18:59 morgan
-# cross platform support
-#
-# Revision 1.1 1996/11/09 19:44:16 morgan
-# Initial revision
-#
-#
+
+include ../../Make.Rules
########################################################################
# some options... uncomment to take effect
########################################################################
-# do you want shadow?
-USE_SHADOW=-D"HAVE_SHADOW_H"
-
+# Unless someone wants to work out how to make this work with the new
+# autoconf stuff, you should use a separate module for this type of thing
+# pam_cracklib perhaps..?
# do you want cracklib?
-ifeq ($(HAVE_CRACKLIB),yes)
-USE_CRACKLIB=-D"USE_CRACKLIB"
-endif
+#ifeq ($(HAVE_CRACKLIB),yes)
+#USE_CRACKLIB=-D"USE_CRACKLIB"
+#endif
# do you want to use lckpwdf?
+ifeq ($(WITH_LCKPWDF),yes)
USE_LCKPWDF=-D"USE_LCKPWDF"
-
# do you need to include the locking functions in the source?
-#NEED_LCKPWDF=-D"NEED_LCKPWDF"
-
-########################################################################
-
-CFLAGS += $(USE_SHADOW) $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF)
+ifeq ($(HAVE_LCKPWDF),no)
+ NEED_LCKPWDF=-D"NEED_LCKPWDF"
+endif
+endif
-ifdef DYNAMIC
-LIBSESSSH = pam_unix_session.so
-LIBAUTHSH = pam_unix_auth.so
-LIBPASSWDSH = pam_unix_passwd.so
-LIBACCOUNT = pam_unix_acct.so
+ifeq ($(HAVE_LIBNSL),yes)
+ LIBNSL = -lnsl
endif
-ifdef STATIC
-LIBSTATIC = libpam_unix.o
+ifeq ($(HAVE_LIBCRYPT),yes)
+ LIBCRYPT=-lcrypt
endif
+CHKPWD=unix_chkpwd
+
+EXTRAS += -DCHKPWD_HELPER=\"$(SUPLEMENTED)/$(CHKPWD)\"
+
+########################################################################
+
+CFLAGS += $(USE_CRACKLIB) $(USE_LCKPWDF) $(NEED_LCKPWDF) $(EXTRAS)
+LDLIBS = $(EXTRALS)
+
ifdef USE_CRACKLIB
CRACKLIB = -lcrack
endif
-LIBAUTHOBJ = pam_unix_auth.o support.o
-LIBAUTHSRC = pam_unix_auth.c support.c
-LIBSESSOBJ = pam_unix_sess.o
-LIBSESSSRC = pam_unix_sess.c
-LIBPASSWDSRC = pam_unix_passwd.c
-LIBPASSWDOBJ = pam_unix_passwd.o
-LIBACCOUNTSRC = pam_unix_acct.c
-LIBACCOUNTOBJ = pam_unix_acct.o
-LIBOBJ = $(LIBAUTHOBJ) $(LIBSESSOBJ) $(LIBPASSWDOBJ) $(LIBACCOUNTOBJ)
-LIBSRC = $(LIBAUTHSRC) $(LIBSESSSRC) $(LIBPASSWDSRC) $(LIBACCOUNTSRC)
-
-LIBSHARED = $(LIBSESSSH) $(LIBAUTHSH) $(LIBPASSWDSH) $(LIBACCOUNT)
+LIBOBJ = pam_unix_auth.o pam_unix_acct.o pam_unix_sess.o pam_unix_passwd.o \
+ support.o
+LIBSRC = pam_unix_auth.c pam_unix_acct.c pam_unix_sess.c pam_unix_passwd.c \
+ support.c
LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
LIBOBJS = $(addprefix static/,$(LIBOBJ))
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) -c $< -o $@
+PLUS = md5_good.o md5_broken.o md5_crypt_good.o md5_crypt_broken.o \
+ yppasswd_xdr.o bigcrypt.o
-static/%.o: %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) -c $< -o $@
+ifdef DYNAMIC
+LIBSHARED = pam_unix.so
+endif
+ifdef STATIC
+LIBSTATIC = libpam_unix.o
+endif
########################### don't edit below #######################
-dummy:
+all: dirs info $(PLUS) $(LIBSHARED) $(LIBSTATIC) $(CHKPWD) register
+
+dynamic/%.o : %.c
+ $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+static/%.o: %.c
+ $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+dummy:
@echo "**** This is not a top-level Makefile "
exit
info:
@echo
- @echo "*** Building pam-unix(alpha) module of the framework..."
+ @echo "*** Building pam-unix module of the framework..."
@echo
-all: dirs info $(LIBSHARED) $(LIBSTATIC) register
-
dirs:
ifdef DYNAMIC
mkdir -p ./dynamic
@@ -105,50 +96,71 @@ endif
register:
ifdef STATIC
- ( cd .. ; \
- ./register_static pam_unix_auth pam_unix/$(LIBSTATIC) ; \
- ./register_static pam_unix_acct "" ; \
+ ( cd .. ; ./register_static pam_unix_auth pam_unix/$(LIBSTATIC) ; \
+ ./register_static pam_unix_acct "" ; \
+ ./register_static pam_unix_session "" ; \
+ ./register_static pam_unix_passwd "" ; \
)
endif
ifdef DYNAMIC
$(LIBOBJD): $(LIBSRC)
-$(LIBAUTHSH): $(LIBAUTHSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBAUTHOBJ)) -lcrypt
-
-$(LIBSESSSH): $(LIBSESSSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBSESSOBJ))
-
-$(LIBPASSWDSH): $(LIBPASSWDSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBPASSWDOBJ)) $(CRACKLIB) -lcrypt
-
-$(LIBACCOUNT): $(LIBACCOUNTSRC) $(LIBOBJD)
- $(LD_D) -o $@ $(addprefix dynamic/,$(LIBACCOUNTOBJ))
+$(LIBSHARED): $(LIBOBJD)
+ $(LD_D) -o $@ $(LIBOBJD) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT)
endif
-
ifdef STATIC
$(LIBOBJS): $(LIBSRC)
$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
+ $(LD) -r -o $@ $(LIBOBJS) $(PLUS) $(CRACKLIB) $(LDLIBS) $(LIBNSL) $(LIBCRYPT)
endif
+$(CHKPWD): unix_chkpwd.o md5_good.o md5_broken.o \
+ md5_crypt_good.o md5_crypt_broken.o \
+ bigcrypt.o
+ $(CC) -o $(CHKPWD) $^ $(LDLIBS) $(LIBCRYPT)
+
+unix_chkpwd.o: unix_chkpwd.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
+
+md5_good.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -DHIGHFIRST -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_broken.o: md5.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_good.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Good##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
+md5_crypt_broken.o: md5_crypt.c
+ $(CC) $(CFLAGS) $(CPPFLAGS) -D'MD5Name(x)=Broken##x' \
+ $(TARGET_ARCH) -c $< -o $@
+
install: all
mkdir -p $(FAKEROOT)$(SECUREDIR)
ifdef DYNAMIC
install -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
+ for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\
+ do ln -sf $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)/$$x.so ; done
endif
+ $(MKDIR) $(FAKEROOT)$(SUPLEMENTED)
+ install -m 4555 $(CHKPWD) $(FAKEROOT)$(SUPLEMENTED)
remove:
- cd $(FAKEROOT)$(SECUREDIR) && rm -f $(LIBSHARED)
+ rm -f $(FAKEROOT)$(SECUREDIR)/$(LIBSHARED)
+ for x in pam_unix_auth pam_unix_acct pam_unix_passwd pam_unix_session;\
+ do rm -f $(FAKEROOT)$(SECUREDIR)/$$x.so ; done
+ rm -f $(FAKEROOT)$(SUPLEMENTED)/$(CHKPWD)
clean:
- rm -f $(LIBOBJD) $(LIBOBJS) a.out core *~
-
-extraclean: clean
- rm -f *.a *.out *.o *.so *.bak
+ rm -f $(LIBOBJD) $(LIBOBJS) $(CHKPWD) *.o *.so core
+ rm -f *~ *.a *.out *.bak
+ rm -rf dynamic static
.c.o:
$(CC) -c $(CFLAGS) $<
diff --git a/contrib/libpam/modules/pam_unix/README b/contrib/libpam/modules/pam_unix/README
index 082e99697da2..ad4bc35e488a 100644
--- a/contrib/libpam/modules/pam_unix/README
+++ b/contrib/libpam/modules/pam_unix/README
@@ -1,39 +1,39 @@
-This is the README for pam_unix in Linux-PAM-0.53.
+This is the README for pam_unix in Linux-PAM-0.67.
--------------------------------------------------
-pam_unix comes as four separate modules:
+pam_unix now comes as one module pam_unix.so.
+The following links are left for compatibility with old versions:
pam_unix_auth: authentication module providing
- pam_authenticate() and pam_setcred() hooks
-
- NO options are recognized. Credential facilities are trivial
- (function simply returns)
-
+ pam_authenticate() and pam_setcred() hooks
pam_unix_sess: session module, providing session logging
-
- "debug" and "trace" arguments are accepted, which indicate the
- logging-level for syslog.
-
- "debug" -> LOG_DEBUG [ also default ]
- "trace" -> LOG_AUTHPRIV
-
pam_unix_acct: account management, providing shadow account
- managment features, password aging etc..
-
- NO options are recognized. Account managment trivial without
- shadow active.
-
+ managment features, password aging etc..
pam_unix_passwd: password updating facilities providing
- cracklib password strength checking facilities.
-
- if compiled, the default behavior is to check passwords
- strictly using CrackLib. This behavior can be turned off
- with the argument
-
- "strict=false"
+ cracklib password strength checking facilities.
+
+The following options are recognized:
+ debug - log more debugging info
+ audit - a little more extreme than debug
+ use_first_pass - don 't prompt the user for passwords
+ take them from PAM_ items instead
+ try_first_pass - don 't prompt the user for the passwords
+ unless PAM_(OLD)AUTHTOK is unset
+ use_authtok - like try_first_pass, but * fail * if the new
+ PAM_AUTHTOK has not been previously set.
+ (intended for stacking password modules only)
+ not_set_pass - don 't set the PAM_ items with the passwords
+ used by this module.
+ shadow - try to maintian a shadow based system.
+ md5 - when a user changes their password next,
+ encrypt it with the md5 algorithm.
+ bigcrypt - when a user changes their password next,
+ excrypt it with the DEC C2 - algorithm(0).
+ nodelay - used to prevent failed authentication
+ resulting in a delay of about 1 second.
+ nis - use NIS RPC for setting new password
+ remember=X - remember X old passwords, they are kept in
+ /etc/security/opasswd in MD5 crypted form
invalid arguments are logged to syslog.
-------------------------------
-- Andrew 1996/11/9
-------------------------------
diff --git a/contrib/libpam/modules/pam_unix/bigcrypt.c b/contrib/libpam/modules/pam_unix/bigcrypt.c
new file mode 100644
index 000000000000..b1568d6b340a
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/bigcrypt.c
@@ -0,0 +1,119 @@
+/*
+ * This function implements the "bigcrypt" algorithm specifically for
+ * Linux-PAM.
+ *
+ * This algorithm is algorithm 0 (default) shipped with the C2 secure
+ * implementation of Digital UNIX.
+ *
+ * Disclaimer: This work is not based on the source code to Digital
+ * UNIX, nor am I connected to Digital Equipment Corp, in any way
+ * other than as a customer. This code is based on published
+ * interfaces and reasonable guesswork.
+ *
+ * Description: The cleartext is divided into blocks of SEGMENT_SIZE=8
+ * characters or less. Each block is encrypted using the standard UNIX
+ * libc crypt function. The result of the encryption for one block
+ * provides the salt for the suceeding block.
+ *
+ * Restrictions: The buffer used to hold the encrypted result is
+ * statically allocated. (see MAX_PASS_LEN below). This is necessary,
+ * as the returned pointer points to "static data that are overwritten
+ * by each call", (XPG3: XSI System Interface + Headers pg 109), and
+ * this is a drop in replacement for crypt();
+ *
+ * Andy Phillips <atp@mssl.ucl.ac.uk>
+ */
+
+#include <string.h>
+#include <security/_pam_macros.h>
+
+char *crypt(const char *key, const char *salt);
+char *bigcrypt(const char *key, const char *salt);
+
+/*
+ * Max cleartext password length in segments of 8 characters this
+ * function can deal with (16 segments of 8 chars= max 128 character
+ * password).
+ */
+
+#define MAX_PASS_LEN 16
+#define SEGMENT_SIZE 8
+#define SALT_SIZE 2
+#define KEYBUF_SIZE ((MAX_PASS_LEN*SEGMENT_SIZE)+SALT_SIZE)
+#define ESEGMENT_SIZE 11
+#define CBUF_SIZE ((MAX_PASS_LEN*ESEGMENT_SIZE)+SALT_SIZE+1)
+
+char *bigcrypt(const char *key, const char *salt)
+{
+ static char dec_c2_cryptbuf[CBUF_SIZE]; /* static storage area */
+
+ unsigned long int keylen, n_seg, j;
+ char *cipher_ptr, *plaintext_ptr, *tmp_ptr, *salt_ptr;
+ char keybuf[KEYBUF_SIZE + 1];
+
+ D(("called with key='%s', salt='%s'.", key, salt));
+
+ /* reset arrays */
+ memset(keybuf, 0, KEYBUF_SIZE + 1);
+ memset(dec_c2_cryptbuf, 0, CBUF_SIZE);
+
+ /* fill KEYBUF_SIZE with key */
+ strncpy(keybuf, key, KEYBUF_SIZE);
+
+ /* deal with case that we are doing a password check for a
+ conventially encrypted password: the salt will be
+ SALT_SIZE+ESEGMENT_SIZE long. */
+ if (strlen(salt) == (SALT_SIZE + ESEGMENT_SIZE))
+ keybuf[SEGMENT_SIZE] = '\0'; /* terminate password early(?) */
+
+ keylen = strlen(keybuf);
+
+ if (!keylen) {
+ n_seg = 1;
+ } else {
+ /* work out how many segments */
+ n_seg = 1 + ((keylen - 1) / SEGMENT_SIZE);
+ }
+
+ if (n_seg > MAX_PASS_LEN)
+ n_seg = MAX_PASS_LEN; /* truncate at max length */
+
+ /* set up some pointers */
+ cipher_ptr = dec_c2_cryptbuf;
+ plaintext_ptr = keybuf;
+
+ /* do the first block with supplied salt */
+ tmp_ptr = crypt(plaintext_ptr, salt); /* libc crypt() */
+
+ /* and place in the static area */
+ strncpy(cipher_ptr, tmp_ptr, 13);
+ cipher_ptr += ESEGMENT_SIZE + SALT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE; /* first block of SEGMENT_SIZE */
+
+ /* change the salt (1st 2 chars of previous block) - this was found
+ by dowsing */
+
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+
+ /* so far this is identical to "return crypt(key, salt);", if
+ there is more than one block encrypt them... */
+
+ if (n_seg > 1) {
+ for (j = 2; j <= n_seg; j++) {
+
+ tmp_ptr = crypt(plaintext_ptr, salt_ptr);
+
+ /* skip the salt for seg!=0 */
+ strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE);
+
+ cipher_ptr += ESEGMENT_SIZE;
+ plaintext_ptr += SEGMENT_SIZE;
+ salt_ptr = cipher_ptr - ESEGMENT_SIZE;
+ }
+ }
+ D(("key=|%s|, salt=|%s|\nbuf=|%s|\n", key, salt, dec_c2_cryptbuf));
+
+ /* this is the <NUL> terminated encrypted password */
+
+ return dec_c2_cryptbuf;
+}
diff --git a/contrib/libpam/modules/pam_unix/lckpwdf.-c b/contrib/libpam/modules/pam_unix/lckpwdf.-c
new file mode 100644
index 000000000000..b5ff45850b4b
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/lckpwdf.-c
@@ -0,0 +1,117 @@
+/*
+ * This is a hack, but until libc and glibc both include this function
+ * by default (libc only includes it if nys is not being used, at the
+ * moment, and glibc doesn't appear to have it at all) we need to have
+ * it here, too. :-(
+ *
+ * This should not become an official part of PAM.
+ *
+ * BEGIN_HACK
+ */
+
+/*
+ * lckpwdf.c -- prevent simultaneous updates of password files
+ *
+ * Before modifying any of the password files, call lckpwdf(). It may block
+ * for up to 15 seconds trying to get the lock. Return value is 0 on success
+ * or -1 on failure. When you are done, call ulckpwdf() to release the lock.
+ * The lock is also released automatically when the process exits. Only one
+ * process at a time may hold the lock.
+ *
+ * These functions are supposed to be conformant with AT&T SVID Issue 3.
+ *
+ * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
+ * public domain.
+ */
+
+#include <fcntl.h>
+#include <signal.h>
+
+#define LOCKFILE "/etc/.pwd.lock"
+#define TIMEOUT 15
+
+static int lockfd = -1;
+
+static int set_close_on_exec(int fd)
+{
+ int flags = fcntl(fd, F_GETFD, 0);
+ if (flags == -1)
+ return -1;
+ flags |= FD_CLOEXEC;
+ return fcntl(fd, F_SETFD, flags);
+}
+
+static int do_lock(int fd)
+{
+ struct flock fl;
+
+ memset(&fl, 0, sizeof fl);
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ return fcntl(fd, F_SETLKW, &fl);
+}
+
+static void alarm_catch(int sig)
+{
+/* does nothing, but fcntl F_SETLKW will fail with EINTR */
+}
+
+static int lckpwdf(void)
+{
+ struct sigaction act, oldact;
+ sigset_t set, oldset;
+
+ if (lockfd != -1)
+ return -1;
+
+ lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
+ if (lockfd == -1)
+ return -1;
+ if (set_close_on_exec(lockfd) == -1)
+ goto cleanup_fd;
+
+ memset(&act, 0, sizeof act);
+ act.sa_handler = alarm_catch;
+ act.sa_flags = 0;
+ sigfillset(&act.sa_mask);
+ if (sigaction(SIGALRM, &act, &oldact) == -1)
+ goto cleanup_fd;
+
+ sigemptyset(&set);
+ sigaddset(&set, SIGALRM);
+ if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1)
+ goto cleanup_sig;
+
+ alarm(TIMEOUT);
+ if (do_lock(lockfd) == -1)
+ goto cleanup_alarm;
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ sigaction(SIGALRM, &oldact, NULL);
+ return 0;
+
+ cleanup_alarm:
+ alarm(0);
+ sigprocmask(SIG_SETMASK, &oldset, NULL);
+ cleanup_sig:
+ sigaction(SIGALRM, &oldact, NULL);
+ cleanup_fd:
+ close(lockfd);
+ lockfd = -1;
+ return -1;
+}
+
+static int ulckpwdf(void)
+{
+ unlink(LOCKFILE);
+ if (lockfd == -1)
+ return -1;
+
+ if (close(lockfd) == -1) {
+ lockfd = -1;
+ return -1;
+ }
+ lockfd = -1;
+ return 0;
+}
+/* END_HACK */
diff --git a/contrib/libpam/modules/pam_unix/md5.c b/contrib/libpam/modules/pam_unix/md5.c
new file mode 100644
index 000000000000..7ee9ed00cdea
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5.c
@@ -0,0 +1,256 @@
+/*
+ * $Id: md5.c,v 1.1.1.1 2000/06/20 22:12:03 agmorgan Exp $
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest. This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ *
+ * To compute the message digest of a chunk of bytes, declare an
+ * MD5Context structure, pass it to MD5Init, call MD5Update as
+ * needed on buffers full of bytes, and then call MD5Final, which
+ * will fill a supplied 16-byte array with the digest.
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+#ifndef HIGHFIRST
+#define byteReverse(buf, len) /* Nothing */
+#else
+static void byteReverse(unsigned char *buf, unsigned longs);
+
+#ifndef ASM_MD5
+/*
+ * Note: this code is harmless on little-endian machines.
+ */
+static void byteReverse(unsigned char *buf, unsigned longs)
+{
+ uint32 t;
+ do {
+ t = (uint32) ((unsigned) buf[3] << 8 | buf[2]) << 16 |
+ ((unsigned) buf[1] << 8 | buf[0]);
+ *(uint32 *) buf = t;
+ buf += 4;
+ } while (--longs);
+}
+#endif
+#endif
+
+/*
+ * Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
+ * initialization constants.
+ */
+void MD5Name(MD5Init)(struct MD5Context *ctx)
+{
+ ctx->buf[0] = 0x67452301U;
+ ctx->buf[1] = 0xefcdab89U;
+ ctx->buf[2] = 0x98badcfeU;
+ ctx->buf[3] = 0x10325476U;
+
+ ctx->bits[0] = 0;
+ ctx->bits[1] = 0;
+}
+
+/*
+ * Update context to reflect the concatenation of another buffer full
+ * of bytes.
+ */
+void MD5Name(MD5Update)(struct MD5Context *ctx, unsigned const char *buf, unsigned len)
+{
+ uint32 t;
+
+ /* Update bitcount */
+
+ t = ctx->bits[0];
+ if ((ctx->bits[0] = t + ((uint32) len << 3)) < t)
+ ctx->bits[1]++; /* Carry from low to high */
+ ctx->bits[1] += len >> 29;
+
+ t = (t >> 3) & 0x3f; /* Bytes already in shsInfo->data */
+
+ /* Handle any leading odd-sized chunks */
+
+ if (t) {
+ unsigned char *p = (unsigned char *) ctx->in + t;
+
+ t = 64 - t;
+ if (len < t) {
+ memcpy(p, buf, len);
+ return;
+ }
+ memcpy(p, buf, t);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += t;
+ len -= t;
+ }
+ /* Process data in 64-byte chunks */
+
+ while (len >= 64) {
+ memcpy(ctx->in, buf, 64);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ buf += 64;
+ len -= 64;
+ }
+
+ /* Handle any remaining bytes of data. */
+
+ memcpy(ctx->in, buf, len);
+}
+
+/*
+ * Final wrapup - pad to 64-byte boundary with the bit pattern
+ * 1 0* (64-bit count of bits processed, MSB-first)
+ */
+void MD5Name(MD5Final)(unsigned char digest[16], struct MD5Context *ctx)
+{
+ unsigned count;
+ unsigned char *p;
+
+ /* Compute number of bytes mod 64 */
+ count = (ctx->bits[0] >> 3) & 0x3F;
+
+ /* Set the first char of padding to 0x80. This is safe since there is
+ always at least one byte free */
+ p = ctx->in + count;
+ *p++ = 0x80;
+
+ /* Bytes of padding needed to make 64 bytes */
+ count = 64 - 1 - count;
+
+ /* Pad out to 56 mod 64 */
+ if (count < 8) {
+ /* Two lots of padding: Pad the first block to 64 bytes */
+ memset(p, 0, count);
+ byteReverse(ctx->in, 16);
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+
+ /* Now fill the next block with 56 bytes */
+ memset(ctx->in, 0, 56);
+ } else {
+ /* Pad block to 56 bytes */
+ memset(p, 0, count - 8);
+ }
+ byteReverse(ctx->in, 14);
+
+ /* Append length in bits and transform */
+ ((uint32 *) ctx->in)[14] = ctx->bits[0];
+ ((uint32 *) ctx->in)[15] = ctx->bits[1];
+
+ MD5Name(MD5Transform)(ctx->buf, (uint32 *) ctx->in);
+ byteReverse((unsigned char *) ctx->buf, 4);
+ memcpy(digest, ctx->buf, 16);
+ memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */
+}
+
+#ifndef ASM_MD5
+
+/* The four core functions - F1 is optimized somewhat */
+
+/* #define F1(x, y, z) (x & y | ~x & z) */
+#define F1(x, y, z) (z ^ (x & (y ^ z)))
+#define F2(x, y, z) F1(z, x, y)
+#define F3(x, y, z) (x ^ y ^ z)
+#define F4(x, y, z) (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define MD5STEP(f, w, x, y, z, data, s) \
+ ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x )
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data. MD5Update blocks
+ * the data and converts bytes into longwords for this routine.
+ */
+void MD5Name(MD5Transform)(uint32 buf[4], uint32 const in[16])
+{
+ register uint32 a, b, c, d;
+
+ a = buf[0];
+ b = buf[1];
+ c = buf[2];
+ d = buf[3];
+
+ MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478U, 7);
+ MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756U, 12);
+ MD5STEP(F1, c, d, a, b, in[2] + 0x242070dbU, 17);
+ MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceeeU, 22);
+ MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0fafU, 7);
+ MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62aU, 12);
+ MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613U, 17);
+ MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501U, 22);
+ MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8U, 7);
+ MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7afU, 12);
+ MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1U, 17);
+ MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7beU, 22);
+ MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122U, 7);
+ MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193U, 12);
+ MD5STEP(F1, c, d, a, b, in[14] + 0xa679438eU, 17);
+ MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821U, 22);
+
+ MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562U, 5);
+ MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340U, 9);
+ MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51U, 14);
+ MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aaU, 20);
+ MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105dU, 5);
+ MD5STEP(F2, d, a, b, c, in[10] + 0x02441453U, 9);
+ MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681U, 14);
+ MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8U, 20);
+ MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6U, 5);
+ MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6U, 9);
+ MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87U, 14);
+ MD5STEP(F2, b, c, d, a, in[8] + 0x455a14edU, 20);
+ MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905U, 5);
+ MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8U, 9);
+ MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9U, 14);
+ MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8aU, 20);
+
+ MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942U, 4);
+ MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681U, 11);
+ MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122U, 16);
+ MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380cU, 23);
+ MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44U, 4);
+ MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9U, 11);
+ MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60U, 16);
+ MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70U, 23);
+ MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6U, 4);
+ MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127faU, 11);
+ MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085U, 16);
+ MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05U, 23);
+ MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039U, 4);
+ MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5U, 11);
+ MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8U, 16);
+ MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665U, 23);
+
+ MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244U, 6);
+ MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97U, 10);
+ MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7U, 15);
+ MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039U, 21);
+ MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3U, 6);
+ MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92U, 10);
+ MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47dU, 15);
+ MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1U, 21);
+ MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4fU, 6);
+ MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0U, 10);
+ MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314U, 15);
+ MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1U, 21);
+ MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82U, 6);
+ MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235U, 10);
+ MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bbU, 15);
+ MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391U, 21);
+
+ buf[0] += a;
+ buf[1] += b;
+ buf[2] += c;
+ buf[3] += d;
+}
+
+#endif
diff --git a/contrib/libpam/modules/pam_unix/md5.h b/contrib/libpam/modules/pam_unix/md5.h
new file mode 100644
index 000000000000..103f168a91c6
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5.h
@@ -0,0 +1,31 @@
+
+#ifndef MD5_H
+#define MD5_H
+
+typedef unsigned int uint32;
+
+struct MD5Context {
+ uint32 buf[4];
+ uint32 bits[2];
+ unsigned char in[64];
+};
+
+void GoodMD5Init(struct MD5Context *);
+void GoodMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void GoodMD5Final(unsigned char digest[16], struct MD5Context *);
+void GoodMD5Transform(uint32 buf[4], uint32 const in[16]);
+void BrokenMD5Init(struct MD5Context *);
+void BrokenMD5Update(struct MD5Context *, unsigned const char *, unsigned);
+void BrokenMD5Final(unsigned char digest[16], struct MD5Context *);
+void BrokenMD5Transform(uint32 buf[4], uint32 const in[16]);
+
+char *Goodcrypt_md5(const char *pw, const char *salt);
+char *Brokencrypt_md5(const char *pw, const char *salt);
+
+/*
+ * This is needed to make RSAREF happy on some MS-DOS compilers.
+ */
+
+typedef struct MD5Context MD5_CTX;
+
+#endif /* MD5_H */
diff --git a/contrib/libpam/modules/pam_unix/md5_crypt.c b/contrib/libpam/modules/pam_unix/md5_crypt.c
new file mode 100644
index 000000000000..257e4bb6bd06
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/md5_crypt.c
@@ -0,0 +1,149 @@
+/*
+ * $Id: md5_crypt.c,v 1.1.1.1 2000/06/20 22:12:03 agmorgan Exp $
+ *
+ * ----------------------------------------------------------------------------
+ * "THE BEER-WARE LICENSE" (Revision 42):
+ * <phk@login.dknet.dk> wrote this file. As long as you retain this notice you
+ * can do whatever you want with this stuff. If we meet some day, and you think
+ * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
+ * ----------------------------------------------------------------------------
+ *
+ * Origin: Id: crypt.c,v 1.3 1995/05/30 05:42:22 rgrimes Exp
+ *
+ */
+
+#include <string.h>
+#include "md5.h"
+
+static unsigned char itoa64[] = /* 0 ... 63 => ascii - 64 */
+"./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+
+static void to64(char *s, unsigned long v, int n)
+{
+ while (--n >= 0) {
+ *s++ = itoa64[v & 0x3f];
+ v >>= 6;
+ }
+}
+
+/*
+ * UNIX password
+ *
+ * Use MD5 for what it is best at...
+ */
+
+char *MD5Name(crypt_md5)(const char *pw, const char *salt)
+{
+ const char *magic = "$1$";
+ /* This string is magic for this algorithm. Having
+ * it this way, we can get get better later on */
+ static char passwd[120], *p;
+ static const char *sp, *ep;
+ unsigned char final[16];
+ int sl, pl, i, j;
+ MD5_CTX ctx, ctx1;
+ unsigned long l;
+
+ /* Refine the Salt first */
+ sp = salt;
+
+ /* If it starts with the magic string, then skip that */
+ if (!strncmp(sp, magic, strlen(magic)))
+ sp += strlen(magic);
+
+ /* It stops at the first '$', max 8 chars */
+ for (ep = sp; *ep && *ep != '$' && ep < (sp + 8); ep++)
+ continue;
+
+ /* get the length of the true salt */
+ sl = ep - sp;
+
+ MD5Name(MD5Init)(&ctx);
+
+ /* The password first, since that is what is most unknown */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)pw,strlen(pw));
+
+ /* Then our magic string */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)magic,strlen(magic));
+
+ /* Then the raw salt */
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)sp,sl);
+
+ /* Then just as many characters of the MD5(pw,salt,pw) */
+ MD5Name(MD5Init)(&ctx1);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ for (pl = strlen(pw); pl > 0; pl -= 16)
+ MD5Name(MD5Update)(&ctx,(unsigned const char *)final,pl>16 ? 16 : pl);
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ /* Then something really weird... */
+ for (j = 0, i = strlen(pw); i; i >>= 1)
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)final+j, 1);
+ else
+ MD5Name(MD5Update)(&ctx, (unsigned const char *)pw+j, 1);
+
+ /* Now make the output string */
+ strcpy(passwd, magic);
+ strncat(passwd, sp, sl);
+ strcat(passwd, "$");
+
+ MD5Name(MD5Final)(final,&ctx);
+
+ /*
+ * and now, just to make sure things don't run too fast
+ * On a 60 Mhz Pentium this takes 34 msec, so you would
+ * need 30 seconds to build a 1000 entry dictionary...
+ */
+ for (i = 0; i < 1000; i++) {
+ MD5Name(MD5Init)(&ctx1);
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+
+ if (i % 3)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)sp,sl);
+
+ if (i % 7)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+
+ if (i & 1)
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)final,16);
+ else
+ MD5Name(MD5Update)(&ctx1,(unsigned const char *)pw,strlen(pw));
+ MD5Name(MD5Final)(final,&ctx1);
+ }
+
+ p = passwd + strlen(passwd);
+
+ l = (final[0] << 16) | (final[6] << 8) | final[12];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[1] << 16) | (final[7] << 8) | final[13];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[2] << 16) | (final[8] << 8) | final[14];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[3] << 16) | (final[9] << 8) | final[15];
+ to64(p, l, 4);
+ p += 4;
+ l = (final[4] << 16) | (final[10] << 8) | final[5];
+ to64(p, l, 4);
+ p += 4;
+ l = final[11];
+ to64(p, l, 2);
+ p += 2;
+ *p = '\0';
+
+ /* Don't leave anything around in vm they could use. */
+ memset(final, 0, sizeof final);
+
+ return passwd;
+}
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_acct.c b/contrib/libpam/modules/pam_unix/pam_unix_acct.c
index 5c0546aa1f8f..178b6037465a 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_acct.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_acct.c
@@ -1,5 +1,6 @@
/*
* Copyright Elliot Lee, 1996. All rights reserved.
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -33,73 +34,159 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/* pam_unix_acct.c module, different track */
-
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+#include <security/_pam_aconf.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#define __USE_MISC
-#include <pwd.h>
+#include <unistd.h>
#include <sys/types.h>
#include <syslog.h>
-#include <unistd.h>
-#ifdef HAVE_SHADOW_H
+#include <pwd.h>
#include <shadow.h>
-#endif
-#include <time.h>
+#include <time.h> /* for time() */
-#define PAM_SM_ACCOUNT
+#include <security/_pam_macros.h>
-#ifndef LINUX
-# include <security/pam_appl.h>
-#endif
+/* indicate that the following groups are defined */
+
+#define PAM_SM_ACCOUNT
-#define _PAM_EXTERN_FUNCTIONS
#include <security/pam_modules.h>
-PAM_EXTERN
-int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
+
+#include "support.h"
+
+/*
+ * PAM framework looks for this entry-point to pass control to the
+ * account management module.
+ */
+
+PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
-#ifdef HAVE_SHADOW_H
- const char *uname;
- int retval;
- time_t curdays;
- struct spwd *spent;
- struct passwd *pwent;
-
- setpwent();
- setspent();
- retval = pam_get_item(pamh,PAM_USER,(const void **)&uname);
- if(retval != PAM_SUCCESS || uname == NULL) {
- return PAM_SUCCESS; /* Couldn't get username, just ignore this
- (i.e. they don't have any expiry info available */
- }
- pwent = getpwnam(uname);
- if(!pwent)
- return PAM_USER_UNKNOWN;
- if(strcmp(pwent->pw_passwd,"x"))
- return PAM_SUCCESS; /* They aren't using shadow passwords & expiry
- info */
- spent = getspnam(uname);
- if(!spent)
- return PAM_SUCCESS; /* Couldn't get username from shadow, just ignore this
- (i.e. they don't have any expiry info available */
- curdays = time(NULL)/(60*60*24);
- if((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
- && (spent->sp_max != -1) && (spent->sp_inact != -1))
- return PAM_ACCT_EXPIRED;
- if((curdays > spent->sp_expire) && (spent->sp_expire != -1))
- return PAM_ACCT_EXPIRED;
- endspent();
- endpwent();
-#endif
- return PAM_SUCCESS;
+ unsigned int ctrl;
+ const char *uname;
+ int retval, daysleft;
+ time_t curdays;
+ struct spwd *spent;
+ struct passwd *pwent;
+ char buf[80];
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &uname);
+ D(("user = `%s'", uname));
+ if (retval != PAM_SUCCESS || uname == NULL) {
+ _log_err(LOG_ALERT, pamh
+ ,"could not identify user (from uid=%d)"
+ ,getuid());
+ return PAM_USER_UNKNOWN;
+ }
+
+ pwent = getpwnam(uname);
+ if (!pwent) {
+ _log_err(LOG_ALERT, pamh
+ ,"could not identify user (from getpwnam(%s))"
+ ,uname);
+ return PAM_USER_UNKNOWN;
+ }
+
+ if (!strcmp( pwent->pw_passwd, "*NP*" )) { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwent->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwent->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwent->pw_uid ) == -1)
+ return PAM_CRED_INSUFFICIENT;
+ }
+ }
+ spent = getspnam( uname );
+ if (save_uid == pwent->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+
+ } else if (!strcmp( pwent->pw_passwd, "x" )) {
+ spent = getspnam(uname);
+ } else {
+ return PAM_SUCCESS;
+ }
+
+ if (!spent)
+ return PAM_AUTHINFO_UNAVAIL; /* Couldn't get username from shadow */
+
+ curdays = time(NULL) / (60 * 60 * 24);
+ D(("today is %d, last change %d", curdays, spent->sp_lstchg));
+ if ((curdays > spent->sp_expire) && (spent->sp_expire != -1)
+ && (spent->sp_lstchg != 0)) {
+ _log_err(LOG_NOTICE, pamh
+ ,"account %s has expired (account expired)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "Your account has expired; please contact your system administrator");
+ D(("account expired"));
+ return PAM_ACCT_EXPIRED;
+ }
+ if ((curdays > (spent->sp_lstchg + spent->sp_max + spent->sp_inact))
+ && (spent->sp_max != -1) && (spent->sp_inact != -1)
+ && (spent->sp_lstchg != 0)) {
+ _log_err(LOG_NOTICE, pamh
+ ,"account %s has expired (failed to change password)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "Your account has expired; please contact your system administrator");
+ D(("account expired 2"));
+ return PAM_ACCT_EXPIRED;
+ }
+ D(("when was the last change"));
+ if (spent->sp_lstchg == 0) {
+ _log_err(LOG_NOTICE, pamh
+ ,"expired password for user %s (root enforced)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You are required to change your password immediately (root enforced)");
+ D(("need a new password"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if (((spent->sp_lstchg + spent->sp_max) < curdays) && (spent->sp_max != -1)) {
+ _log_err(LOG_DEBUG, pamh
+ ,"expired password for user %s (password aged)"
+ ,uname);
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You are required to change your password immediately (password aged)");
+ D(("need a new password 2"));
+ return PAM_NEW_AUTHTOK_REQD;
+ }
+ if ((curdays > (spent->sp_lstchg + spent->sp_max - spent->sp_warn))
+ && (spent->sp_max != -1) && (spent->sp_warn != -1)) {
+ daysleft = (spent->sp_lstchg + spent->sp_max) - curdays;
+ _log_err(LOG_DEBUG, pamh
+ ,"password for user %s will expire in %d days"
+ ,uname, daysleft);
+ snprintf(buf, 80, "Warning: your password will expire in %d day%.2s",
+ daysleft, daysleft == 1 ? "" : "s");
+ _make_remark(pamh, ctrl, PAM_TEXT_INFO, buf);
+ }
+
+ D(("all done"));
+
+ return PAM_SUCCESS;
}
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_auth.c b/contrib/libpam/modules/pam_unix/pam_unix_auth.c
index 95f13d0abdc6..f08ea515b4d4 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_auth.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_auth.c
@@ -1,8 +1,7 @@
-/* $Header: /home/morgan/pam/Linux-PAM-0.59/modules/pam_unix/RCS/pam_unix_auth.c,v 1.1 1996/11/09 19:44:35 morgan Exp morgan $ */
-
/*
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
* NIS+ support by Thorsten Kukuk <kukuk@weber.uni-paderborn.de>
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -35,217 +34,145 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-
-/*
- * $Log: pam_unix_auth.c,v $
- *
- * Revision 1.9 1996/05/26 04:13:04 morgan
- * added static support
- *
- * Revision 1.8 1996/05/21 03:51:58 morgan
- * added "const" to rcsid[] definition
- *
- * Revision 1.7 1996/04/19 03:25:57 alex
- * minor corrections.
- *
- * Revision 1.6 1996/04/17 01:05:05 alex
- * _pam_auth_unix() cleaned up - non-authentication code is made into funcs
- * and mostly moved out to support.c.
- *
- * Revision 1.5 1996/04/16 21:12:46 alex
- * unix authentication works on Bach again. This is a tranitional stage.
- * I really don't like that _pam_unix_auth() grew into a monster that does
- * prompts etc etc. They should go into other functions.
- *
- * Revision 1.4 1996/04/07 08:06:12 morgan
- * tidied up a little
- *
- * Revision 1.3 1996/04/07 07:34:07 morgan
- * added conversation support. Now the module is capable of obtaining a
- * username and a password all by itself.
- *
- * Revision 1.2 1996/03/29 02:31:19 morgan
- * Marek Michalkiewicz's small patches for shadow support.
- *
- * Revision 1.1 1996/03/09 09:10:57 morgan
- * Initial revision
- *
- */
-#ifdef linux
-# define _GNU_SOURCE
-# include <features.h>
-#endif
+/* #define DEBUG */
+
+#include <security/_pam_aconf.h>
-#include <stdlib.h>
#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
#include <string.h>
-#define __USE_BSD
#include <unistd.h>
-#include <pwd.h>
+#include <fcntl.h>
+#include <ctype.h>
#include <sys/types.h>
+#include <sys/stat.h>
-#ifndef NDEBUG
-
-#include <syslog.h>
-
-#endif /* NDEBUG */
-
-#ifdef HAVE_SHADOW_H
-
-#include <shadow.h>
-
-#endif /* HAVE_SHADOW_H */
-
-#ifndef LINUX
-
-#include <security/pam_appl.h>
+/* indicate the following groups are defined */
-#endif /* LINUX */
+#define PAM_SM_AUTH
#define _PAM_EXTERN_FUNCTIONS
+#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-static const char rcsid[] = "$Id: pam_unix_auth.c,v 1.1 1996/11/09 19:44:35 morgan Exp morgan $ pam_unix authentication functions. alex@bach.cis.temple.edu";
-
-/* Define function phototypes */
-
-extern char *crypt(const char *key, const char *salt); /* This should have
- been in unistd.h
- but it is not */
-extern int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response );
-
-extern int _set_auth_tok( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv );
-
-static int _pam_auth_unix( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv );
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
-static int _pam_set_credentials_unix ( pam_handle_t *pamh,
- int flags,
- int argc,
- const char ** argv ) ;
+#include "support.h"
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * authentication module.
+ */
/* Fun starts here :)
- *
- * _pam_auth_unix() actually performs UNIX/shadow authentication
+
+ * pam_sm_authenticate() performs UNIX/shadow authentication
*
- * First, if shadow support is available, attempt to perform
- * authentication using shadow passwords. If shadow is not
- * available, or user does not have a shadow password, fallback
- * onto a normal UNIX authentication
+ * First, if shadow support is available, attempt to perform
+ * authentication using shadow passwords. If shadow is not
+ * available, or user does not have a shadow password, fallback
+ * onto a normal UNIX authentication
*/
-static int _pam_auth_unix( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
+#define _UNIX_AUTHTOK "-UN*X-PASS"
+
+#define AUTH_RETURN \
+{ \
+ if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) { \
+ D(("recording return code for next time [%d]", \
+ retval)); \
+ pam_set_data(pamh, "unix_setcred_return", \
+ (void *) retval, NULL); \
+ } \
+ D(("done. [%s]", pam_strerror(pamh, retval))); \
+ return retval; \
+}
+
+PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
+ ,int argc, const char **argv)
{
- int retval;
- struct passwd *pw;
- const char *name;
- char *p, *pp;
- const char *salt;
+ unsigned int ctrl;
+ int retval, *ret_data = NULL;
+ const char *name, *p;
-#ifdef HAVE_SHADOW_H
+ D(("called."));
- struct spwd *sp;
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
-#endif
+ /* Get a few bytes so we can pass our return value to
+ pam_sm_setcred(). */
+ ret_data = malloc(sizeof(int));
/* get the user'name' */
- if ( (retval = pam_get_user( pamh, &name, "login: ") ) != PAM_SUCCESS )
- return retval;
-
- /*
- * at some point we will have to make this module pay
- * attention to arguments, like 'pam_first_pass' etc...
- */
-
- pw = getpwnam ( name );
+ retval = pam_get_user(pamh, &name, "login: ");
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't take
+ * any chances here. Require that the username starts with an
+ * alphanumeric character.
+ */
+ if (name == NULL || !isalnum(*name)) {
+ _log_err(LOG_ERR, pamh, "bad username [%s]", name);
+ retval = PAM_USER_UNKNOWN;
+ AUTH_RETURN
+ }
+ if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
+ D(("username [%s] obtained", name));
+ } else {
+ D(("trouble reading username"));
+ if (retval == PAM_CONV_AGAIN) {
+ D(("pam_get_user/conv() function is not ready yet"));
+ /* it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ }
+ AUTH_RETURN
+ }
- /* For NIS+, root cannot get password for lesser user */
- if (pw) {
- uid_t save_euid, save_uid;
+ /* if this user does not have a password... */
- save_uid = getuid ();
- save_euid = geteuid();
- if (setreuid (0,pw->pw_uid) >= 0) {
- pw = getpwnam ( name );
- setreuid (save_uid,save_euid);
- }
+ if (_unix_blankpasswd(ctrl, name)) {
+ D(("user '%s' has blank passwd", name));
+ name = NULL;
+ retval = PAM_SUCCESS;
+ AUTH_RETURN
}
-
- if ( pw && (!pw->pw_passwd || pw->pw_passwd[0] == '\0') &&
- !(flags & PAM_DISALLOW_NULL_AUTHTOK)) {
- return PAM_SUCCESS;
+ /* get this user's authentication token */
+
+ retval = _unix_read_password(pamh, ctrl, NULL, "Password: ", NULL
+ ,_UNIX_AUTHTOK, &p);
+ if (retval != PAM_SUCCESS) {
+ if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_CRIT, pamh, "auth could not identify password for [%s]"
+ ,name);
+ } else {
+ D(("conversation function is not ready yet"));
+ /*
+ * it is safe to resume this function so we translate this
+ * retval to the value that indicates we're happy to resume.
+ */
+ retval = PAM_INCOMPLETE;
+ }
+ name = NULL;
+ AUTH_RETURN
}
- pam_get_item( pamh, PAM_AUTHTOK, (void*) &p );
-
- if ( !p )
- {
- retval = _set_auth_tok( pamh, flags, argc, argv );
- if ( retval != PAM_SUCCESS )
- return retval;
- }
-
- /*
- We have to call pam_get_item() again because value of p should
- change
- */
-
- pam_get_item( pamh, PAM_AUTHTOK, (void*) &p );
+ D(("user=%s, password=[%s]", name, p));
+ /* verify the password of this user */
+ retval = _unix_verify_password(pamh, name, p, ctrl);
+ name = p = NULL;
- if (pw)
- {
-
-#ifdef HAVE_SHADOW_H
-
- /*
- * Support for shadow passwords on Linux and SVR4-based
- * systems. Shadow passwords are optional on Linux - if
- * there is no shadow password, use the non-shadow one.
- */
-
- sp = getspnam( name );
- if (sp && (!strcmp(pw->pw_passwd,"x")))
- {
- /* TODO: check if password has expired etc. */
- salt = sp->sp_pwdp;
- }
- else
-#endif
- salt = pw->pw_passwd;
- }
- else
- return PAM_USER_UNKNOWN;
-
- /* The 'always-encrypt' method does not make sense in PAM
- because the framework requires return of a different
- error code for non-existant users -- alex */
-
- if ( ( !pw->pw_passwd ) && ( !p ) )
- if ( flags && PAM_DISALLOW_NULL_AUTHTOK )
- return PAM_SUCCESS;
- else
- return PAM_AUTH_ERR;
-
- pp = crypt(p, salt);
-
- if ( strcmp( pp, salt ) == 0 )
- return PAM_SUCCESS;
-
- return PAM_AUTH_ERR;
+ AUTH_RETURN
}
+
/*
* The only thing _pam_set_credentials_unix() does is initialization of
* UNIX group IDs.
@@ -255,45 +182,35 @@ static int _pam_auth_unix( pam_handle_t *pamh,
* warned you. -- AOY
*/
-static int _pam_set_credentials_unix ( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-
-{ /* FIX ME: incorrect error code */
-
- return PAM_SUCCESS; /* This is a wrong result code. From what I
- remember from reafing one of the guides
- there's an error-level saying 'N/A func'
- -- AOY
- */
-}
-
-/*
- * PAM framework looks for these entry-points to pass control to the
- * authentication module.
- */
-
-PAM_EXTERN
-int pam_sm_authenticate( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- return _pam_auth_unix( pamh, flags, argc, argv );
-}
-
-PAM_EXTERN
-int pam_sm_setcred( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv)
+PAM_EXTERN int pam_sm_setcred(pam_handle_t * pamh, int flags
+ ,int argc, const char **argv)
{
- return _pam_set_credentials_unix ( pamh, flags, argc, argv ) ;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ /* FIXME: it shouldn't be necessary to parse the arguments again. The
+ only argument we need is UNIX_LIKE_AUTH: if it was set,
+ pam_get_data will succeed. If it wasn't, it will fail, and we
+ return PAM_SUCCESS. -SRL */
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+ retval = PAM_SUCCESS;
+
+ if (on(UNIX_LIKE_AUTH, ctrl)) {
+ int *pretval = NULL;
+
+ D(("recovering return code from auth call"));
+ pam_get_data(pamh, "unix_setcred_return", (const void **) pretval);
+ if(pretval) {
+ retval = *pretval;
+ free(pretval);
+ D(("recovered data indicates that old retval was %d", retval));
+ }
+ }
+ return retval;
}
-
-/* static module data */
#ifdef PAM_STATIC
struct pam_module _pam_unix_auth_modstruct = {
"pam_unix_auth",
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_passwd.c b/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
index de1345e85285..3fe8a27a6997 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_passwd.c
@@ -1,8 +1,7 @@
-
-/* Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
- Copyright (C) 1996. */
-
/*
+ * Main coding by Elliot Lee <sopwith@redhat.com>, Red Hat Software.
+ * Copyright (C) 1996.
+ * Copyright (c) Jan Rêkorajski, 1999.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -16,13 +15,13 @@
* 3. The name of the author may not be used to endorse or promote
* products derived from this software without specific prior
* written permission.
- *
+ *
* ALTERNATIVELY, this product may be distributed under the terms of
* the GNU Public License, in which case the provisions of the GPL are
* required INSTEAD OF the above restrictions. (This clause is
* necessary due to a potential bad interaction between the GPL and
* the restrictions contained in a BSD-style copyright.)
- *
+ *
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
@@ -36,778 +35,970 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- How it works:
- Gets in username (has to be done) from the calling program
- Does authentication of user (only if we are not running as root)
- Gets new password/checks for sanity
- Sets it.
- */
-
-#define PAM_SM_PASSWORD
-
-/* #define DEBUG 1 */
+#include <security/_pam_aconf.h>
#include <stdio.h>
-#include <sys/time.h>
-#define _BSD_SOURCE
-#define _SVID_SOURCE
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <unistd.h>
#include <errno.h>
-#define __USE_BSD
-#define _BSD_SOURCE
-#include <pwd.h>
#include <sys/types.h>
+#include <pwd.h>
+#include <syslog.h>
+#include <shadow.h>
+#include <time.h> /* for time() */
+#include <fcntl.h>
+#include <ctype.h>
+#include <sys/time.h>
+#include <sys/stat.h>
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
-/* why not defined? */
-void setpwent(void);
-void endpwent(void);
-int chmod(const char *path, mode_t mode);
-struct passwd *fgetpwent(FILE *stream);
-int putpwent(const struct passwd *p, FILE *stream);
-
-#include <unistd.h>
-char *crypt(const char *key, const char *salt);
#ifdef USE_CRACKLIB
#include <crack.h>
#endif
-#include <ctype.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <syslog.h>
-#include <string.h>
-#include <stdarg.h>
-#include <malloc.h>
+
#include <security/_pam_macros.h>
-#ifndef LINUX /* AGM added this as of 0.2 */
-#include <security/pam_appl.h>
-#endif /* ditto */
+/* indicate the following groups are defined */
+
+#define PAM_SM_PASSWORD
+
#include <security/pam_modules.h>
-#ifdef HAVE_SHADOW_H
-#include <shadow.h>
-#endif
-#define MAX_PASSWD_TRIES 3
-#define OLD_PASSWORD_PROMPT "Password: "
-#define NEW_PASSWORD_PROMPT "New password: "
-#define AGAIN_PASSWORD_PROMPT "New password (again): "
-#define PW_TMPFILE "/etc/npasswd"
-#define SH_TMPFILE "/etc/nshadow"
-#define CRACKLIB_DICTS "/usr/lib/cracklib_dict"
-
-/* Various flags for the getpass routine to send back in... */
-#define PPW_EXPIRED 1
-#define PPW_EXPIRING 2
-#define PPW_WILLEXPIRE 4
-#define PPW_NOSUCHUSER 8
-#define PPW_SHADOW 16
-#define PPW_TOOEARLY 32
-#define PPW_ERROR 64
-
-#ifndef DO_TEST
-#define STATIC static
-#else
-#define STATIC
-#endif
-/* Sets a password for the specified user to the specified password
- Returns flags PPW_*, or'd. */
-STATIC int _do_setpass(char *forwho, char *towhat, int flags);
-/* Gets a password for the specified user
- Returns flags PPW_*, or'd. */
-STATIC int _do_getpass(char *forwho, char **theirpass);
-/* Checks whether the password entered is same as listed in the database
- 'entered' should not be crypt()'d or anything (it should be as the
- user entered it...), 'listed' should be as it is listed in the
- password database file */
-STATIC int _do_checkpass(const char *entered, char *listed);
-
-/* sends a one-way message to the user, either error or info... */
-STATIC int conv_sendmsg(struct pam_conv *aconv, const char *message, int style);
-/* sends a message and returns the results of the conversation */
-STATIC int conv_getitem(struct pam_conv *aconv, char *message, int style,
- char **result);
-
-PAM_EXTERN
-int pam_sm_chauthtok( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv);
-
-static void _pam_log(int err, const char *format, ...)
-{
- va_list args;
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
- va_start(args, format);
- openlog("PAM-unix_passwd", LOG_CONS|LOG_PID, LOG_AUTH);
- vsyslog(err, format, args);
- va_end(args);
- closelog();
-}
+#include "yppasswd.h"
+#include "md5.h"
+#include "support.h"
+
+#if !((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 1))
+extern int getrpcport(const char *host, unsigned long prognum,
+ unsigned long versnum, unsigned int proto);
+#endif /* GNU libc 2.1 */
+
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * password changing module.
+ */
#ifdef NEED_LCKPWDF
-/* This is a hack, but until libc and glibc both include this function
- * by default (libc only includes it if nys is not being used, at the
- * moment, and glibc doesn't appear to have it at all) we need to have
- * it here, too. :-(
- *
- * This should not become an official part of PAM.
- *
- * BEGIN_HACK
-*/
+#include "./lckpwdf.-c"
+#endif
+
+extern char *bigcrypt(const char *key, const char *salt);
/*
- * lckpwdf.c -- prevent simultaneous updates of password files
- *
- * Before modifying any of the password files, call lckpwdf(). It may block
- * for up to 15 seconds trying to get the lock. Return value is 0 on success
- * or -1 on failure. When you are done, call ulckpwdf() to release the lock.
- * The lock is also released automatically when the process exits. Only one
- * process at a time may hold the lock.
- *
- * These functions are supposed to be conformant with AT&T SVID Issue 3.
- *
- * Written by Marek Michalkiewicz <marekm@i17linuxb.ists.pwr.wroc.pl>,
- * public domain.
+ How it works:
+ Gets in username (has to be done) from the calling program
+ Does authentication of user (only if we are not running as root)
+ Gets new password/checks for sanity
+ Sets it.
*/
-#include <fcntl.h>
-#include <signal.h>
+/* passwd/salt conversion macros */
-#define LOCKFILE "/etc/.pwd.lock"
-#define TIMEOUT 15
+#define ascii_to_bin(c) ((c)>='a'?(c-59):(c)>='A'?((c)-53):(c)-'.')
+#define bin_to_ascii(c) ((c)>=38?((c)-38+'a'):(c)>=12?((c)-12+'A'):(c)+'.')
-static int lockfd = -1;
+/* data tokens */
-static int
-set_close_on_exec(int fd)
+#define _UNIX_OLD_AUTHTOK "-UN*X-OLD-PASS"
+#define _UNIX_NEW_AUTHTOK "-UN*X-NEW-PASS"
+
+#define MAX_PASSWD_TRIES 3
+#define PW_TMPFILE "/etc/npasswd"
+#define SH_TMPFILE "/etc/nshadow"
+#define CRACKLIB_DICTS "/usr/share/dict/cracklib_dict"
+#define OPW_TMPFILE "/etc/security/nopasswd"
+#define OLD_PASSWORDS_FILE "/etc/security/opasswd"
+
+/*
+ * i64c - convert an integer to a radix 64 character
+ */
+static int i64c(int i)
{
- int flags = fcntl(fd, F_GETFD, 0);
- if (flags == -1)
- return -1;
- flags |= FD_CLOEXEC;
- return fcntl(fd, F_SETFD, flags);
+ if (i < 0)
+ return ('.');
+ else if (i > 63)
+ return ('z');
+ if (i == 0)
+ return ('.');
+ if (i == 1)
+ return ('/');
+ if (i >= 2 && i <= 11)
+ return ('0' - 2 + i);
+ if (i >= 12 && i <= 37)
+ return ('A' - 12 + i);
+ if (i >= 38 && i <= 63)
+ return ('a' - 38 + i);
+ return ('\0');
}
-static int
-do_lock(int fd)
+static char *crypt_md5_wrapper(const char *pass_new)
{
- struct flock fl;
+ /*
+ * Code lifted from Marek Michalkiewicz's shadow suite. (CG)
+ * removed use of static variables (AGM)
+ */
+
+ struct timeval tv;
+ MD5_CTX ctx;
+ unsigned char result[16];
+ char *cp = (char *) result;
+ unsigned char tmp[16];
+ int i;
+ char *x, *e = NULL;
+
+ GoodMD5Init(&ctx);
+ gettimeofday(&tv, (struct timezone *) 0);
+ GoodMD5Update(&ctx, (void *) &tv, sizeof tv);
+ i = getpid();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ i = clock();
+ GoodMD5Update(&ctx, (void *) &i, sizeof i);
+ GoodMD5Update(&ctx, result, sizeof result);
+ GoodMD5Final(tmp, &ctx);
+ strcpy(cp, "$1$"); /* magic for the MD5 */
+ cp += strlen(cp);
+ for (i = 0; i < 8; i++)
+ *cp++ = i64c(tmp[i] & 077);
+ *cp = '\0';
+
+ /* no longer need cleartext */
+ e = Goodcrypt_md5(pass_new, (const char *) result);
+ x = x_strdup(e); /* put e in malloc()ed memory */
+ _pam_overwrite(e); /* clean up */
+
+ return x;
+}
- memset(&fl, 0, sizeof fl);
- fl.l_type = F_WRLCK;
- fl.l_whence = SEEK_SET;
- return fcntl(fd, F_SETLKW, &fl);
+static char *getNISserver(pam_handle_t *pamh)
+{
+ char *master;
+ char *domainname;
+ int port, err;
+
+ if ((err = yp_get_default_domain(&domainname)) != 0) {
+ _log_err(LOG_WARNING, pamh, "can't get local yp domain: %s\n",
+ yperr_string(err));
+ return NULL;
+ }
+ if ((err = yp_master(domainname, "passwd.byname", &master)) != 0) {
+ _log_err(LOG_WARNING, pamh, "can't find the master ypserver: %s\n",
+ yperr_string(err));
+ return NULL;
+ }
+ port = getrpcport(master, YPPASSWDPROG, YPPASSWDPROC_UPDATE, IPPROTO_UDP);
+ if (port == 0) {
+ _log_err(LOG_WARNING, pamh,
+ "yppasswdd not running on NIS master host\n");
+ return NULL;
+ }
+ if (port >= IPPORT_RESERVED) {
+ _log_err(LOG_WARNING, pamh,
+ "yppasswd daemon running on illegal port.\n");
+ return NULL;
+ }
+ return master;
}
-static void
-alarm_catch(int sig)
+static int check_old_password(const char *forwho, const char *newpass)
{
-/* does nothing, but fcntl F_SETLKW will fail with EINTR */
+ static char buf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas;
+ int retval = PAM_SUCCESS;
+ FILE *opwfile;
+
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf) - 1] = '\0';
+ s_luser = strtok(buf, ":,");
+ s_uid = strtok(NULL, ":,");
+ s_npas = strtok(NULL, ":,");
+ s_pas = strtok(NULL, ":,");
+ while (s_pas != NULL) {
+ if (!strcmp(Goodcrypt_md5(newpass, s_pas), s_pas)) {
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ s_pas = strtok(NULL, ":,");
+ }
+ break;
+ }
+ }
+ fclose(opwfile);
+
+ return retval;
}
-static int lckpwdf(void)
+static int save_old_password(const char *forwho, const char *oldpass, int howmany)
{
- struct sigaction act, oldact;
- sigset_t set, oldset;
-
- if (lockfd != -1)
- return -1;
-
- lockfd = open(LOCKFILE, O_CREAT | O_WRONLY, 0600);
- if (lockfd == -1)
- return -1;
- if (set_close_on_exec(lockfd) == -1)
- goto cleanup_fd;
-
- memset(&act, 0, sizeof act);
- act.sa_handler = alarm_catch;
- act.sa_flags = 0;
- sigfillset(&act.sa_mask);
- if (sigaction(SIGALRM, &act, &oldact) == -1)
- goto cleanup_fd;
-
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
- if (sigprocmask(SIG_UNBLOCK, &set, &oldset) == -1)
- goto cleanup_sig;
-
- alarm(TIMEOUT);
- if (do_lock(lockfd) == -1)
- goto cleanup_alarm;
- alarm(0);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
- sigaction(SIGALRM, &oldact, NULL);
- return 0;
-
-cleanup_alarm:
- alarm(0);
- sigprocmask(SIG_SETMASK, &oldset, NULL);
-cleanup_sig:
- sigaction(SIGALRM, &oldact, NULL);
-cleanup_fd:
- close(lockfd);
- lockfd = -1;
- return -1;
+ static char buf[16384];
+ static char nbuf[16384];
+ char *s_luser, *s_uid, *s_npas, *s_pas, *pass;
+ int retval = 0, npas;
+ FILE *pwfile, *opwfile;
+ int err = 0;
+ int oldmask;
+ int found = 0;
+ struct passwd *pwd = NULL;
+
+ if (howmany < 0)
+ return retval;
+
+ if (oldpass == NULL)
+ return retval;
+
+ oldmask = umask(077);
+ pwfile = fopen(OPW_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(OPW_TMPFILE, 0, 0);
+ chmod(OPW_TMPFILE, 0600);
+
+ while (fgets(buf, 16380, opwfile)) {
+ if (!strncmp(buf, forwho, strlen(forwho))) {
+ buf[strlen(buf) - 1] = '\0';
+ s_luser = strtok(buf, ":");
+ s_uid = strtok(NULL, ":");
+ s_npas = strtok(NULL, ":");
+ s_pas = strtok(NULL, ":");
+ npas = strtol(s_npas, NULL, 10) + 1;
+ while (npas > howmany) {
+ s_pas = strpbrk(s_pas, ",");
+ if (s_pas != NULL)
+ s_pas++;
+ npas--;
+ }
+ pass = crypt_md5_wrapper(oldpass);
+ if (s_pas == NULL)
+ sprintf(nbuf, "%s:%s:%d:%s\n", s_luser, s_uid, npas, pass);
+ else
+ sprintf(nbuf, "%s:%s:%d:%s,%s\n", s_luser, s_uid, npas, s_pas, pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ break;
+ }
+ found = 1;
+ } else if (fputs(buf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ break;
+ }
+ }
+ fclose(opwfile);
+ if (!found) {
+ pwd = getpwnam(forwho);
+ if (pwd == NULL) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ } else {
+ pass = crypt_md5_wrapper(oldpass);
+ sprintf(nbuf, "%s:%d:1:%s\n", forwho, pwd->pw_uid, pass);
+ if (fputs(nbuf, pwfile) < 0) {
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ }
+ }
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to old passwords file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ if (!err)
+ rename(OPW_TMPFILE, OLD_PASSWORDS_FILE);
+ else
+ unlink(OPW_TMPFILE);
+
+ return retval;
}
-static int
-ulckpwdf(void)
+static int _update_passwd(const char *forwho, const char *towhat)
{
- unlink(LOCKFILE);
- if (lockfd == -1)
- return -1;
+ struct passwd *tmpent = NULL;
+ FILE *pwfile, *opwfile;
+ int retval = 0;
+ int err = 0;
+ int oldmask;
+
+ oldmask = umask(077);
+ pwfile = fopen(PW_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen("/etc/passwd", "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(PW_TMPFILE, 0, 0);
+ chmod(PW_TMPFILE, 0644);
+ tmpent = fgetpwent(opwfile);
+ while (tmpent) {
+ if (!strcmp(tmpent->pw_name, forwho)) {
+ tmpent->pw_passwd = towhat;
+ }
+ if (putpwent(tmpent, pwfile)) {
+ fprintf(stderr, "error writing entry to password file: %s\n",
+ strerror(errno));
+ err = 1;
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ tmpent = fgetpwent(opwfile);
+ }
+ fclose(opwfile);
- if (close(lockfd) == -1) {
- lockfd = -1;
- return -1;
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to password file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
}
- lockfd = -1;
- return 0;
+ if (!err)
+ rename(PW_TMPFILE, "/etc/passwd");
+ else
+ unlink(PW_TMPFILE);
+
+ return retval;
}
-/* END_HACK */
-#endif
-#define PAM_FAIL_CHECK if(retval != PAM_SUCCESS) { return retval; }
+static int _update_shadow(const char *forwho, char *towhat)
+{
+ struct spwd *spwdent = NULL, *stmpent = NULL;
+ FILE *pwfile, *opwfile;
+ int retval = 0;
+ int err = 0;
+ int oldmask;
+
+ spwdent = getspnam(forwho);
+ if (spwdent == NULL)
+ return PAM_USER_UNKNOWN;
+ oldmask = umask(077);
+ pwfile = fopen(SH_TMPFILE, "w");
+ umask(oldmask);
+ opwfile = fopen("/etc/shadow", "r");
+ if (pwfile == NULL || opwfile == NULL)
+ return PAM_AUTHTOK_ERR;
+ chown(SH_TMPFILE, 0, 0);
+ chmod(SH_TMPFILE, 0600);
+ stmpent = fgetspent(opwfile);
+ while (stmpent) {
+ if (!strcmp(stmpent->sp_namp, forwho)) {
+ stmpent->sp_pwdp = towhat;
+ stmpent->sp_lstchg = time(NULL) / (60 * 60 * 24);
+
+ D(("Set password %s for %s", stmpent->sp_pwdp, forwho));
+ }
+ if (putspent(stmpent, pwfile)) {
+ fprintf(stderr, "error writing entry to shadow file: %s\n",
+ strerror(errno));
+ err = 1;
+ retval = PAM_AUTHTOK_ERR;
+ break;
+ }
+ stmpent = fgetspent(opwfile);
+ }
+ fclose(opwfile);
+
+ if (fclose(pwfile)) {
+ fprintf(stderr, "error writing entries to shadow file: %s\n",
+ strerror(errno));
+ retval = PAM_AUTHTOK_ERR;
+ err = 1;
+ }
+ if (!err)
+ rename(SH_TMPFILE, "/etc/shadow");
+ else
+ unlink(SH_TMPFILE);
+
+ return retval;
+}
-PAM_EXTERN
-int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv)
+static int _do_setpass(pam_handle_t* pamh, const char *forwho, char *fromwhat,
+ char *towhat, unsigned int ctrl, int remember)
{
- char *usrname, *curpass, *newpass; /* pointers to the username,
- current password, and new password */
-
- struct pam_conv *appconv; /* conversation with the app */
- struct pam_message msg, *pmsg; /* Misc for conversations */
- struct pam_response *resp;
-
- int retval=0; /* Gets the return values for all our function calls */
- unsigned int pflags=0; /* Holds the flags from our getpass & setpass
- functions */
-
- const char *cmiscptr; /* Utility variables, used for different purposes at
- different times */
- char *miscptr; /* Utility variables, used for different purposes at
- different times */
- unsigned int miscint;
- int fascist = 1; /* Be fascist by default. If compiled with cracklib,
- call cracklib. Otherwise just check length... */
-
- char argbuf[256],argval[256];
- int i;
-
-
- retval = pam_get_item(pamh,PAM_CONV,(const void **) &appconv);
- PAM_FAIL_CHECK;
-
- retval = pam_get_item(pamh,PAM_USER,(const void **) &usrname);
- PAM_FAIL_CHECK;
- if(flags & PAM_PRELIM_CHECK) {
- pflags = _do_getpass(usrname,&miscptr);
- if(pflags & PPW_NOSUCHUSER)
- return PAM_USER_UNKNOWN;
- else if(pflags & ~(PPW_SHADOW|PPW_EXPIRING|PPW_WILLEXPIRE))
- return PAM_AUTHTOK_ERR;
- else
- return PAM_SUCCESS;
- } /* else... */
+ struct passwd *pwd = NULL;
+ int retval = 0;
+
+ D(("called"));
+
+ setpwent();
+ pwd = getpwnam(forwho);
+ endpwent();
+
+ if (pwd == NULL)
+ return PAM_AUTHTOK_ERR;
+
+ if (on(UNIX_NIS, ctrl)) {
+ struct timeval timeout;
+ struct yppasswd yppwd;
+ CLIENT *clnt;
+ char *master;
+ int status;
+ int err = 0;
+
+ /* Make RPC call to NIS server */
+ if ((master = getNISserver(pamh)) == NULL)
+ return PAM_TRY_AGAIN;
+
+ /* Initialize password information */
+ yppwd.newpw.pw_passwd = pwd->pw_passwd;
+ yppwd.newpw.pw_name = pwd->pw_name;
+ yppwd.newpw.pw_uid = pwd->pw_uid;
+ yppwd.newpw.pw_gid = pwd->pw_gid;
+ yppwd.newpw.pw_gecos = pwd->pw_gecos;
+ yppwd.newpw.pw_dir = pwd->pw_dir;
+ yppwd.newpw.pw_shell = pwd->pw_shell;
+ yppwd.oldpass = fromwhat;
+ yppwd.newpw.pw_passwd = towhat;
+
+ D(("Set password %s for %s", yppwd.newpw.pw_passwd, forwho));
+
+ /* The yppasswd.x file said `unix authentication required',
+ * so I added it. This is the only reason it is in here.
+ * My yppasswdd doesn't use it, but maybe some others out there
+ * do. --okir
+ */
+ clnt = clnt_create(master, YPPASSWDPROG, YPPASSWDVERS, "udp");
+ clnt->cl_auth = authunix_create_default();
+ memset((char *) &status, '\0', sizeof(status));
+ timeout.tv_sec = 25;
+ timeout.tv_usec = 0;
+ err = clnt_call(clnt, YPPASSWDPROC_UPDATE,
+ (xdrproc_t) xdr_yppasswd, (char *) &yppwd,
+ (xdrproc_t) xdr_int, (char *) &status,
+ timeout);
+
+ if (err) {
+ clnt_perrno(err);
+ retval = PAM_TRY_AGAIN;
+ } else if (status) {
+ fprintf(stderr, "Error while changing NIS password.\n");
+ retval = PAM_TRY_AGAIN;
+ }
+ printf("\nThe password has%s been changed on %s.\n",
+ (err || status) ? " not" : "", master);
+
+ auth_destroy(clnt->cl_auth);
+ clnt_destroy(clnt);
+ if ((err || status) != 0) {
+ retval = PAM_TRY_AGAIN;
+ }
#ifdef DEBUG
- fprintf(stderr,"Got username of %s\n",usrname);
+ sleep(5);
#endif
- if((usrname == NULL) || (strlen(usrname) < 1)) {
- /* The app is supposed to get us the username! */
- retval = PAM_USER_UNKNOWN;
- PAM_FAIL_CHECK;
- }
-
- for(i=0; i < argc; i++) {
- {
- char *tmp = x_strdup(argv[i]);
- strncpy(argbuf,strtok(tmp ,"="),255);
- strncpy(argval,strtok(NULL,"="),255);
- free(tmp);
- }
-
- /* For PC functionality use "strict" -- historically "fascist" */
- if(!strcmp(argbuf,"strict") || !strcmp(argbuf, "fascist"))
-
- if(!strcmp(argval,"true"))
- fascist = 1;
- else if(!strcmp(argval,"false"))
- fascist = 0;
- else
- return PAM_SERVICE_ERR;
- else {
- _pam_log(LOG_ERR,"Unknown option: %s",argbuf);
- return PAM_SERVICE_ERR;
- }
- }
-
-
- /* Now we have all the initial information we need from the app to
- set things up (we assume that getting the username succeeded...) */
- retval = pam_get_item(pamh,PAM_OLDAUTHTOK,(const void **) &curpass);
- PAM_FAIL_CHECK;
- if(getuid()) { /* If this is being run by root, we don't need to get their
- old password.
- note */
- /* If we haven't been given a password yet, prompt for one... */
- miscint=0;
- while((curpass == NULL) && (miscint++ < MAX_PASSWD_TRIES)) {
- pflags = _do_getpass(usrname,&miscptr);
- if(pflags & PPW_NOSUCHUSER)
- return PAM_USER_UNKNOWN; /* If the user that was passed in doesn't
- exist, say so and exit (app passes in
- username) */
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = OLD_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- curpass = resp->resp;
- free (resp);
- if(_do_checkpass(curpass?curpass:"",miscptr)) {
- int abortme = 0;
-
- /* password is incorrect... */
- if (curpass && curpass[0] == '\0') {
- /* ...and it was zero-length; user wishes to abort change */
- abortme = 1;
- }
- if (curpass) { free (curpass); }
- curpass = NULL;
- if (abortme) {
- conv_sendmsg(appconv,"Password change aborted.",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- }
- }
-
- if(curpass == NULL)
- return PAM_AUTH_ERR; /* They didn't seem to enter the right password
- for three tries - error */
- pam_set_item(pamh, PAM_OLDAUTHTOK, (void *)curpass);
- } else {
-#ifdef DEBUG
- fprintf(stderr,"I am ROOT!\n");
-#endif
- pflags = _do_getpass(usrname,&curpass);
- if(curpass == NULL)
- curpass = x_strdup("");
- }
- if(pflags & PPW_TOOEARLY) {
- conv_sendmsg(appconv,"You must wait longer to change your password",
- PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(pflags & PPW_WILLEXPIRE)
- conv_sendmsg(appconv,"Your password is about to expire",PAM_TEXT_INFO);
- else if(pflags & PPW_EXPIRED)
- return PAM_ACCT_EXPIRED; /* If their account has expired, we can't auth
- them to change their password */
- if(!(pflags & PPW_EXPIRING) && (flags & PAM_CHANGE_EXPIRED_AUTHTOK))
- return PAM_SUCCESS;
- /* If we haven't been given a password yet, prompt for one... */
- miscint=0;
- pam_get_item(pamh,PAM_AUTHTOK,(const void **)&newpass);
- cmiscptr = NULL;
- while((newpass == NULL) && (miscint++ < MAX_PASSWD_TRIES)) {
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = NEW_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- newpass = resp->resp;
- free (resp);
+ return retval;
+ }
+ /* first, save old password */
+ if (save_old_password(forwho, fromwhat, remember)) {
+ return PAM_AUTHTOK_ERR;
+ }
+ if (on(UNIX_SHADOW, ctrl) || (strcmp(pwd->pw_passwd, "x") == 0)) {
+ retval = _update_shadow(forwho, towhat);
+ if (retval == PAM_SUCCESS)
+ retval = _update_passwd(forwho, "x");
+ } else {
+ retval = _update_passwd(forwho, towhat);
+ }
-#ifdef DEBUG
- if(newpass)
- fprintf(stderr,"Got password of %s\n",newpass);
- else
- fprintf(stderr,"No new password...\n");
-#endif
- if (newpass[0] == '\0') { free (newpass); newpass = (char *) 0; }
- cmiscptr=NULL;
- if(newpass) {
+ return retval;
+}
+
+static int _unix_verify_shadow(const char *user, unsigned int ctrl)
+{
+ struct passwd *pwd = NULL; /* Password and shadow password */
+ struct spwd *spwdent = NULL; /* file entries for the user */
+ time_t curdays;
+ int retval = PAM_SUCCESS;
+
+ /* UNIX passwords area */
+ setpwent();
+ pwd = getpwnam(user); /* Get password file entry... */
+ endpwent();
+ if (pwd == NULL)
+ return PAM_AUTHINFO_UNAVAIL; /* We don't need to do the rest... */
+
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /* ...and shadow password file entry for this user, if shadowing
+ is enabled */
+ setspent();
+ spwdent = getspnam(user);
+ endspent();
+
+ if (spwdent == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ } else {
+ if (strcmp(pwd->pw_passwd,"*NP*") == 0) { /* NIS+ */
+ uid_t save_uid;
+
+ save_uid = geteuid();
+ seteuid (pwd->pw_uid);
+ spwdent = getspnam( user );
+ seteuid (save_uid);
+
+ if (spwdent == NULL)
+ return PAM_AUTHINFO_UNAVAIL;
+ } else
+ spwdent = NULL;
+ }
+
+ if (spwdent != NULL) {
+ /* We have the user's information, now let's check if their account
+ has expired (60 * 60 * 24 = number of seconds in a day) */
+
+ if (off(UNIX__IAMROOT, ctrl)) {
+ /* Get the current number of days since 1970 */
+ curdays = time(NULL) / (60 * 60 * 24);
+ if ((curdays < (spwdent->sp_lstchg + spwdent->sp_min))
+ && (spwdent->sp_min != -1))
+ retval = PAM_AUTHTOK_ERR;
+ else if ((curdays > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
+ && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1)
+ && (spwdent->sp_lstchg != 0))
+ /*
+ * Their password change has been put off too long,
+ */
+ retval = PAM_ACCT_EXPIRED;
+ else if ((curdays > spwdent->sp_expire) && (spwdent->sp_expire != -1)
+ && (spwdent->sp_lstchg != 0))
+ /*
+ * OR their account has just plain expired
+ */
+ retval = PAM_ACCT_EXPIRED;
+ }
+ }
+ return retval;
+}
+
+static int _pam_unix_approve_pass(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *pass_old
+ ,const char *pass_new)
+{
+ const char *user;
+ const char *remark = NULL;
+ int retval = PAM_SUCCESS;
+
+ D(("&new=%p, &old=%p", pass_old, pass_new));
+ D(("new=[%s]", pass_new));
+ D(("old=[%s]", pass_old));
+
+ if (pass_new == NULL || (pass_old && !strcmp(pass_old, pass_new))) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_DEBUG, pamh, "bad authentication token");
+ }
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, pass_new == NULL ?
+ "No password supplied" : "Password unchanged");
+ return PAM_AUTHTOK_ERR;
+ }
+ /*
+ * if one wanted to hardwire authentication token strength
+ * checking this would be the place - AGM
+ */
+
+ retval = pam_get_item(pamh, PAM_USER, (const void **) &user);
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_ERR, pamh, "Can not get username");
+ return PAM_AUTHTOK_ERR;
+ }
+ }
+ if (off(UNIX__IAMROOT, ctrl)) {
#ifdef USE_CRACKLIB
- if(fascist && getuid())
- cmiscptr = FascistCheck(newpass,CRACKLIB_DICTS);
+ remark = FascistCheck(pass_new, CRACKLIB_DICTS);
+ D(("called cracklib [%s]", remark));
#else
- if(fascist && getuid() && strlen(newpass) < 6)
- cmiscptr = "You must choose a longer password";
+ if (strlen(pass_new) < 6)
+ remark = "You must choose a longer password";
+ D(("lenth check [%s]", remark));
#endif
- if(curpass)
- if(!strcmp(curpass,newpass)) {
- cmiscptr="You must choose a new password.";
- newpass=NULL;
+ if (on(UNIX_REMEMBER_PASSWD, ctrl))
+ if ((retval = check_old_password(user, pass_new)) != PAM_SUCCESS)
+ remark = "Password has been already used. Choose another.";
}
- } else {
- /* We want to abort the password change */
- conv_sendmsg(appconv,"Password change aborted",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(!cmiscptr) {
- /* We ask them to enter their password again... */
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = PAM_PROMPT_ECHO_OFF;
- msg.msg = AGAIN_PASSWORD_PROMPT;
- resp = NULL;
-
- retval = appconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, appconv->appdata_ptr);
-
- PAM_FAIL_CHECK;
- miscptr = resp->resp;
- free (resp);
- if (miscptr[0] == '\0') { free (miscptr); miscptr = (char *) 0; }
- if(!miscptr) { /* Aborting password change... */
- conv_sendmsg(appconv,"Password change aborted",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- }
- if(!strcmp(newpass,miscptr)) {
- miscptr=NULL;
- break;
- }
- conv_sendmsg(appconv,"You must enter the same password twice.",
- PAM_ERROR_MSG);
- miscptr=NULL;
- newpass=NULL;
- }
- else {
- conv_sendmsg(appconv,cmiscptr,PAM_ERROR_MSG);
- newpass = NULL;
- }
- }
- if(cmiscptr) {
- /* conv_sendmsg(appconv,cmiscptr,PAM_ERROR_MSG); */
- return PAM_AUTHTOK_ERR;
- } else if(newpass == NULL)
- return PAM_AUTHTOK_ERR; /* They didn't seem to enter the right password
- for three tries - error */
-#ifdef DEBUG
- printf("Changing password for sure!\n");
-#endif
- /* From now on, we are bound and determined to get their password
- changed :-) */
- pam_set_item(pamh, PAM_AUTHTOK, (void *)newpass);
- retval = _do_setpass(usrname,newpass,pflags);
-#ifdef DEBUG
- fprintf(stderr,"retval was %d\n",retval);
-#endif
- if(retval & ~PPW_SHADOW) {
- conv_sendmsg(appconv,"Error: Password NOT changed",PAM_ERROR_MSG);
- return PAM_AUTHTOK_ERR;
- } else {
- conv_sendmsg(appconv,"Password changed",PAM_TEXT_INFO);
- return PAM_SUCCESS;
- }
+ if (remark) {
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark);
+ retval = PAM_AUTHTOK_ERR;
+ }
+ return retval;
}
-/* _do_checkpass() returns 0 on success, non-0 on failure */
-STATIC int _do_checkpass(const char *entered, char *listed)
+
+PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
- char salt[3];
- if ((strlen(listed) == 0) &&(strlen(entered) == 0)) {
- /* no password in database; no password entered */
- return (0);
- }
- salt[0]=listed[0]; salt[1]=listed[1]; salt[2]='\0';
- return strcmp(crypt(entered,salt),listed);
-}
+ unsigned int ctrl, lctrl;
+ int retval, i;
+ int remember = -1;
-STATIC char mksalt(int seed) {
- int num = seed % 64;
-
- if (num < 26)
- return 'a' + num;
- else if (num < 52)
- return 'A' + (num - 26);
- else if (num < 62)
- return '0' + (num - 52);
- else if (num == 63)
- return '.';
- else
- return '/';
-}
+ /* <DO NOT free() THESE> */
+ const char *user;
+ char *pass_old, *pass_new;
+ /* </DO NOT free() THESE> */
-STATIC int _do_setpass(char *forwho, char *towhat,int flags)
-{
- struct passwd *pwd=NULL, *tmpent=NULL;
- FILE *pwfile,*opwfile;
- char thesalt[3];
- int retval=0;
- struct timeval time1;
- int err = 0;
-#ifdef HAVE_SHADOW_H
- struct spwd *spwdent=NULL, *stmpent=NULL;
+ D(("called."));
+
+#ifdef USE_LCKPWDF
+ /* our current locking system requires that we lock the
+ entire password database. This avoids both livelock
+ and deadlock. */
+ /* These values for the number of attempts and the sleep time
+ are, of course, completely arbitrary.
+ My reading of the PAM docs is that, once pam_chauthtok() has been
+ called with PAM_UPDATE_AUTHTOK, we are obliged to take any
+ reasonable steps to make sure the token is updated; so retrying
+ for 1/10 sec. isn't overdoing it.
+ The other possibility is to call lckpwdf() on the first
+ pam_chauthtok() pass, and hold the lock until released in the
+ second pass--but is this guaranteed to work? -SRL */
+ i=0;
+ while((retval = lckpwdf()) != 0 && i < 100) {
+ usleep(1000);
+ }
+ if(retval != 0) {
+ return PAM_AUTHTOK_LOCK_BUSY;
+ }
#endif
- if(flags & PPW_SHADOW) { retval |= PPW_SHADOW; }
- gettimeofday(&time1, NULL);
- srand(time1.tv_usec);
- thesalt[0]=mksalt(rand());
- thesalt[1]=mksalt(rand());
- thesalt[2]='\0';
-
- /* lock the entire password subsystem */
+ ctrl = _set_ctrl(pamh, flags, &remember, argc, argv);
+
+ /*
+ * First get the name of a user
+ */
+ retval = pam_get_user(pamh, &user, "Username: ");
+ if (retval == PAM_SUCCESS) {
+ /*
+ * Various libraries at various times have had bugs related to
+ * '+' or '-' as the first character of a user name. Don't take
+ * any chances here. Require that the username starts with an
+ * alphanumeric character.
+ */
+ if (user == NULL || !isalnum(*user)) {
+ _log_err(LOG_ERR, pamh, "bad username [%s]", user);
#ifdef USE_LCKPWDF
- lckpwdf();
+ ulckpwdf();
#endif
- setpwent();
- pwd = getpwnam(forwho);
-#ifdef DEBUG
- printf("Got %p, for %s (salt %s)\n",pwd,
- forwho,thesalt);
+ return PAM_USER_UNKNOWN;
+ }
+ if (retval == PAM_SUCCESS && on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh, "username [%s] obtained",
+ user);
+ } else {
+ if (on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh,
+ "password - could not identify user");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- if(pwd == NULL)
- return PPW_NOSUCHUSER;
- endpwent();
-
-#ifdef HAVE_SHADOW_H
- if(flags & PPW_SHADOW) {
- spwdent = getspnam(forwho);
- if(spwdent == NULL)
- return PPW_NOSUCHUSER;
- spwdent->sp_pwdp = towhat;
- spwdent->sp_lstchg = time(NULL)/(60*60*24);
- pwfile = fopen(SH_TMPFILE,"w");
- opwfile = fopen("/etc/shadow","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(SH_TMPFILE,0,0);
- chmod(SH_TMPFILE,0600);
- stmpent=fgetspent(opwfile);
- while(stmpent) {
- if(!strcmp(stmpent->sp_namp,forwho)) {
- stmpent->sp_pwdp = crypt(towhat,thesalt);
- stmpent->sp_lstchg = time(NULL)/(60*60*24);
-#ifdef DEBUG
- fprintf(stderr,"Set password %s for %s\n",stmpent->sp_pwdp,
- forwho);
+ return retval;
+ }
+
+ D(("Got username of %s", user));
+
+ /*
+ * This is not an AUTH module!
+ */
+ if (on(UNIX__NONULL, ctrl))
+ set(UNIX__NULLOK, ctrl);
+
+ if (on(UNIX__PRELIM, ctrl)) {
+ /*
+ * obtain and verify the current password (OLDAUTHTOK) for
+ * the user.
+ */
+ char *Announce;
+
+ D(("prelim check"));
+
+ if (_unix_blankpasswd(ctrl, user)) {
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- }
- if (putspent(stmpent,pwfile)) {
- fprintf(stderr, "error writing entry to shadow file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- stmpent=fgetspent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to shadow file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(SH_TMPFILE,"/etc/shadow");
- else
- unlink(SH_TMPFILE);
- } else {
- pwd->pw_passwd = towhat;
- pwfile = fopen(PW_TMPFILE,"w");
- opwfile = fopen("/etc/passwd","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(PW_TMPFILE,0,0);
- chmod(PW_TMPFILE,0644);
- tmpent=fgetpwent(opwfile);
- while(tmpent) {
- if(!strcmp(tmpent->pw_name,forwho)) {
- tmpent->pw_passwd = crypt(towhat,thesalt);
- }
- if (putpwent(tmpent,pwfile)) {
- fprintf(stderr, "error writing entry to password file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- tmpent=fgetpwent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to password file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(PW_TMPFILE,"/etc/passwd");
- else
- unlink(PW_TMPFILE);
- }
-#else
- pwd->pw_passwd = towhat;
- pwfile = fopen(PW_TMPFILE,"w");
- opwfile = fopen("/etc/passwd","r");
- if(pwfile == NULL || opwfile == NULL)
- return PPW_ERROR;
- chown(PW_TMPFILE,0,0);
- chmod(PW_TMPFILE,0644);
- tmpent=fgetpwent(opwfile);
- while(tmpent) {
- if(!strcmp(tmpent->pw_name,forwho)) {
- tmpent->pw_passwd = crypt(towhat,thesalt);
- }
- if (putpwent(tmpent,pwfile)) {
- fprintf(stderr, "error writing entry to shadow file: %s\n",
- strerror(errno));
- err = 1;
- retval = PPW_ERROR;
- break;
- }
- tmpent=fgetpwent(opwfile);
- }
- fclose(opwfile);
-
- if (fclose(pwfile)) {
- fprintf(stderr, "error writing entries to password file: %s\n",
- strerror(errno));
- retval = PPW_ERROR;
- err = 1;
- }
-
- if (!err)
- rename(PW_TMPFILE,"/etc/passwd");
- else
- unlink(PW_TMPFILE);
+ return PAM_SUCCESS;
+ } else if (off(UNIX__IAMROOT, ctrl)) {
+
+ /* instruct user what is happening */
+#define greeting "Changing password for "
+ Announce = (char *) malloc(sizeof(greeting) + strlen(user));
+ if (Announce == NULL) {
+ _log_err(LOG_CRIT, pamh,
+ "password - out of memory");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- /* unlock the entire password subsystem */
+ return PAM_BUF_ERR;
+ }
+ (void) strcpy(Announce, greeting);
+ (void) strcpy(Announce + sizeof(greeting) - 1, user);
+#undef greeting
+
+ lctrl = ctrl;
+ set(UNIX__OLD_PASSWD, lctrl);
+ retval = _unix_read_password(pamh, lctrl
+ ,Announce
+ ,"(current) UNIX password: "
+ ,NULL
+ ,_UNIX_OLD_AUTHTOK
+ ,(const char **) &pass_old);
+ free(Announce);
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh
+ ,"password - (old) token not obtained");
#ifdef USE_LCKPWDF
- ulckpwdf();
+ ulckpwdf();
#endif
- return retval;
-}
-
-STATIC int _do_getpass(char *forwho, char **theirpass)
-{
- struct passwd *pwd=NULL; /* Password and shadow password */
-#ifdef HAVE_SHADOW_H
- struct spwd *spwdent=NULL; /* file entries for the user */
- time_t curdays;
+ return retval;
+ }
+ /* verify that this is the password for this user */
+
+ retval = _unix_verify_password(pamh, user, pass_old, ctrl);
+ } else {
+ D(("process run by root so do nothing this time around"));
+ pass_old = NULL;
+ retval = PAM_SUCCESS; /* root doesn't have too */
+ }
+
+ if (retval != PAM_SUCCESS) {
+ D(("Authentication failed"));
+ pass_old = NULL;
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
- int retval=0;
- /* UNIX passwords area */
- setpwent();
- pwd = getpwnam(forwho); /* Get password file entry... */
- endpwent();
- if(pwd == NULL)
- return PPW_NOSUCHUSER; /* We don't need to do the rest... */
-#ifdef HAVE_SHADOW_H
- if(!strcmp(pwd->pw_passwd,"x")) {
- /* ...and shadow password file entry for this user, if shadowing
- is enabled */
- retval |= PPW_SHADOW;
- setspent();
- spwdent = getspnam(forwho);
- endspent();
- if(spwdent == NULL)
- return PPW_NOSUCHUSER;
- *theirpass = x_strdup(spwdent->sp_pwdp);
-
- /* We have the user's information, now let's check if their account
- has expired (60 * 60 * 24 = number of seconds in a day) */
-
- /* Get the current number of days since 1970 */
- curdays = time(NULL)/(60*60*24);
- if((curdays < (spwdent->sp_lstchg + spwdent->sp_min))
- && (spwdent->sp_min != -1))
- retval |= PPW_TOOEARLY;
- else if((curdays
- > (spwdent->sp_lstchg + spwdent->sp_max + spwdent->sp_inact))
- && (spwdent->sp_max != -1) && (spwdent->sp_inact != -1))
- /* Their password change has been put off too long,
- OR their account has just plain expired */
- retval |= PPW_EXPIRED;
- else if((curdays > (spwdent->sp_lstchg + spwdent->sp_max))
- && (spwdent->sp_max != -1))
- /* Their passwd needs to be changed */
- retval |= PPW_EXPIRING;
- else if((curdays > (spwdent->sp_lstchg
- + spwdent->sp_max - spwdent->sp_warn))
- && (spwdent->sp_max != -1) && (spwdent->sp_warn != -1))
- retval |= PPW_WILLEXPIRE;
-/* if(spwdent->sp_lstchg < 0)
- retval &= ~(PPW_WILLEXPIRE | PPW_EXPIRING | PPW_EXPIRED);
- if(spwdent->sp_max < 0)
- retval &= ~(PPW_EXPIRING | PPW_EXPIRED); */
- } else {
- *theirpass = (char *)x_strdup(pwd->pw_passwd);
- }
-
-#else
- *theirpass = (char *) x_strdup(pwd->pw_passwd);
+ return retval;
+ }
+ retval = pam_set_item(pamh, PAM_OLDAUTHTOK, (const void *) pass_old);
+ pass_old = NULL;
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "failed to set PAM_OLDAUTHTOK");
+ }
+ retval = _unix_verify_shadow(user, ctrl);
+ if (retval == PAM_AUTHTOK_ERR) {
+ if (off(UNIX__IAMROOT, ctrl))
+ _make_remark(pamh, ctrl, PAM_ERROR_MSG,
+ "You must wait longer to change your password");
+ else
+ retval = PAM_SUCCESS;
+ }
+ } else if (on(UNIX__UPDATE, ctrl)) {
+ /*
+ * tpass is used below to store the _pam_md() return; it
+ * should be _pam_delete()'d.
+ */
+
+ char *tpass = NULL;
+ int retry = 0;
+
+ /*
+ * obtain the proposed password
+ */
+
+ D(("do update"));
+
+ /*
+ * get the old token back. NULL was ok only if root [at this
+ * point we assume that this has already been enforced on a
+ * previous call to this function].
+ */
+
+ if (off(UNIX_NOT_SET_PASS, ctrl)) {
+ retval = pam_get_item(pamh, PAM_OLDAUTHTOK
+ ,(const void **) &pass_old);
+ } else {
+ retval = pam_get_data(pamh, _UNIX_OLD_AUTHTOK
+ ,(const void **) &pass_old);
+ if (retval == PAM_NO_MODULE_DATA) {
+ retval = PAM_SUCCESS;
+ pass_old = NULL;
+ }
+ }
+ D(("pass_old [%s]", pass_old));
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh, "user not authenticated");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ retval = _unix_verify_shadow(user, ctrl);
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh, "user not authenticated 2");
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ D(("get new password now"));
+
+ lctrl = ctrl;
+
+ if (on(UNIX_USE_AUTHTOK, lctrl)) {
+ set(UNIX_USE_FIRST_PASS, lctrl);
+ }
+ retry = 0;
+ retval = PAM_AUTHTOK_ERR;
+ while ((retval != PAM_SUCCESS) && (retry++ < MAX_PASSWD_TRIES)) {
+ /*
+ * use_authtok is to force the use of a previously entered
+ * password -- needed for pluggable password strength checking
+ */
+
+ retval = _unix_read_password(pamh, lctrl
+ ,NULL
+ ,"Enter new UNIX password: "
+ ,"Retype new UNIX password: "
+ ,_UNIX_NEW_AUTHTOK
+ ,(const char **) &pass_new);
+
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_ALERT, pamh
+ ,"password - new password not obtained");
+ }
+ pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ D(("returned to _unix_chauthtok"));
+
+ /*
+ * At this point we know who the user is and what they
+ * propose as their new password. Verify that the new
+ * password is acceptable.
+ */
+
+ if (pass_new[0] == '\0') { /* "\0" password = NULL */
+ pass_new = NULL;
+ }
+ retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+ }
+
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_NOTICE, pamh,
+ "new password not acceptable");
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ pass_new = pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
+ }
+ /*
+ * By reaching here we have approved the passwords and must now
+ * rebuild the password database file.
+ */
+
+ /*
+ * First we encrypt the new password.
+ */
+
+ if (on(UNIX_MD5_PASS, ctrl)) {
+ tpass = crypt_md5_wrapper(pass_new);
+ } else {
+ /*
+ * Salt manipulation is stolen from Rick Faith's passwd
+ * program. Sorry Rick :) -- alex
+ */
+
+ time_t tm;
+ char salt[3];
+
+ time(&tm);
+ salt[0] = bin_to_ascii(tm & 0x3f);
+ salt[1] = bin_to_ascii((tm >> 6) & 0x3f);
+ salt[2] = '\0';
+
+ if (off(UNIX_BIGCRYPT, ctrl) && strlen(pass_new) > 8) {
+ /*
+ * to avoid using the _extensions_ of the bigcrypt()
+ * function we truncate the newly entered password
+ */
+ char *temp = malloc(9);
+ char *e;
+
+ if (temp == NULL) {
+ _log_err(LOG_CRIT, pamh,
+ "out of memory for password");
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ pass_new = pass_old = NULL; /* tidy up */
+#ifdef USE_LCKPWDF
+ ulckpwdf();
#endif
+ return PAM_BUF_ERR;
+ }
+ /* copy first 8 bytes of password */
+ strncpy(temp, pass_new, 8);
+ temp[8] = '\0';
+
+ /* no longer need cleartext */
+ e = bigcrypt(temp, salt);
+ tpass = x_strdup(e);
+
+ _pam_overwrite(e);
+ _pam_delete(temp); /* tidy up */
+ } else {
+ char *e;
+
+ /* no longer need cleartext */
+ e = bigcrypt(pass_new, salt);
+ tpass = x_strdup(e);
+
+ _pam_overwrite(e);
+ }
+ }
+
+ D(("password processed"));
+
+ /* update the password database(s) -- race conditions..? */
+
+ retval = _do_setpass(pamh, user, pass_old, tpass, ctrl,
+ remember);
+ _pam_overwrite(pass_new);
+ _pam_overwrite(pass_old);
+ _pam_delete(tpass);
+ pass_old = pass_new = NULL;
+ } else { /* something has broken with the module */
+ _log_err(LOG_ALERT, pamh,
+ "password received unknown request");
+ retval = PAM_ABORT;
+ }
- return retval;
-}
+ D(("retval was %d", retval));
-STATIC int conv_sendmsg(struct pam_conv *aconv, const char *message, int style)
-{
- struct pam_message msg,*pmsg;
- struct pam_response *resp;
- int retval;
-
- /* Get the password from the user... */
- pmsg = &msg;
-
- msg.msg_style = style;
- msg.msg = message;
- resp = NULL;
-
- retval = aconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, aconv->appdata_ptr);
- if (resp) {
- _pam_drop_reply(resp, 1);
- }
- return retval;
+#ifdef USE_LCKPWDF
+ ulckpwdf();
+#endif
+ return retval;
}
-STATIC int conv_getitem(struct pam_conv *aconv, char *message, int style,
- char **result)
-{
- struct pam_message msg,*pmsg;
- struct pam_response *resp;
- int retval;
-
- D(("called."));
-
- /* Get the password from the user... */
- pmsg = &msg;
- msg.msg_style = style;
- msg.msg = message;
- resp = NULL;
-
- retval = aconv->conv(1, (const struct pam_message **) &pmsg,
- &resp, aconv->appdata_ptr);
- if(retval != PAM_SUCCESS)
- return retval;
- if(resp != NULL) {
- *result = resp->resp; free(resp);
- return PAM_SUCCESS;
- }
- else
- return PAM_SERVICE_ERR;
-}
+/* static module data */
+#ifdef PAM_STATIC
+struct pam_module _pam_unix_passwd_modstruct = {
+ "pam_unix_passwd",
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_chauthtok,
+};
+#endif
+
diff --git a/contrib/libpam/modules/pam_unix/pam_unix_sess.c b/contrib/libpam/modules/pam_unix/pam_unix_sess.c
index 319b2ed6288e..d0785006772c 100644
--- a/contrib/libpam/modules/pam_unix/pam_unix_sess.c
+++ b/contrib/libpam/modules/pam_unix/pam_unix_sess.c
@@ -1,9 +1,8 @@
-/*
- * $Header: /home/morgan/pam/Linux-PAM-0.53/modules/pam_unix/RCS/pam_unix_sess.c,v 1.1 1996/11/09 19:44:35 morgan Exp $
- */
-
/*
+ * $Id: pam_unix_sess.c,v 1.3 2000/12/20 05:15:05 vorlon Exp $
+ *
* Copyright Alexander O. Yuriev, 1996. All rights reserved.
+ * Copyright Jan Rêkorajski, 1999. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -37,145 +36,106 @@
* OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-/*
- * $Log: pam_unix_sess.c,v $
- * Revision 1.1 1996/11/09 19:44:35 morgan
- * Initial revision
- *
- * Revision 1.4 1996/05/21 03:55:17 morgan
- * added "const" to definition of rcsid[]
- *
- * Revision 1.3 1996/04/23 16:32:28 alex
- * nothing really got changed.
- *
- * Revision 1.2 1996/04/19 03:23:33 alex
- * session code implemented. account management moved into pam_unix_acct.c
- *
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-#include <pwd.h>
+#include <security/_pam_aconf.h>
-#ifndef LINUX /* AGM added this as of 0.2 */
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
- #include <security/pam_appl.h>
+/* indicate the following groups are defined */
-#endif /* ditto */
+#define PAM_SM_SESSION
+#include <security/_pam_macros.h>
#include <security/pam_modules.h>
-#include <syslog.h>
-#include <unistd.h>
-#ifndef LOG_AUTHPRIV
-#define LOG_AUTHPRIV LOG_AUTH
-#endif
-
-static const char rcsid[] = "$Id: pam_unix_sess.c,v 1.1 1996/11/09 19:44:35 morgan Exp $ pam_unix session management. alex@bach.cis.temple.edu";
-
-/* Define internal functions */
-static int _get_log_level( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
-
-int _pam_unix_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+#ifndef LINUX_PAM
+#include <security/pam_appl.h>
+#endif /* LINUX_PAM */
-int _pam_unix_close_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+#include "support.h"
-/* Implementation */
+/*
+ * PAM framework looks for these entry-points to pass control to the
+ * session module.
+ */
-static int _get_log_level( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
+PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
- int i = argc;
- int log_level = LOG_DEBUG;
-
- while ( i-- )
- {
- if ( strcmp( *argv, "debug" ) == 0 )
- log_level = LOG_DEBUG;
- else if ( strcmp ( *argv, "trace" ) == 0 )
- log_level = LOG_AUTHPRIV;
- argv++;
- }
-
- return log_level;
-}
+ char *user_name, *service;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "open_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "open_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ _log_err(LOG_INFO, pamh, "session opened for user %s by %s(uid=%d)"
+ ,user_name
+ ,PAM_getlogin() == NULL ? "" : PAM_getlogin(), getuid());
-int _pam_unix_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- int log_level;
- char *user_name, *service;
-
-
- log_level = _get_log_level( pamh, flags, argc, argv );
-
- pam_get_item( pamh, PAM_USER, (void*) &user_name );
- if ( !user_name )
- return PAM_CONV_ERR; /* How did we get authenticated with
- no username?! */
-
- pam_get_item( pamh, PAM_SERVICE, (void*) &service );
- if ( !service )
- return PAM_CONV_ERR;
-
- syslog ( log_level,
- "pam_unix authentication session started, user %s, service %s\n",
- user_name, service );
-
return PAM_SUCCESS;
}
-int _pam_unix_close_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
+PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags,
+ int argc, const char **argv)
{
- int log_level;
- char *user_name, *service;
-
- log_level = _get_log_level( pamh, flags, argc, argv );
-
- pam_get_item( pamh, PAM_USER, (void*) &user_name );
- if ( !user_name )
- return PAM_CONV_ERR; /* How did we get authenticated with
- no username?! */
-
- pam_get_item( pamh, PAM_SERVICE, (void*) &service );
- if ( !service )
- return PAM_CONV_ERR;
-
- syslog ( log_level,
- "pam_unix authentication session finished, user %s, service %s\n",
- user_name, service );
-
- return PAM_SUCCESS;
-}
+ char *user_name, *service;
+ unsigned int ctrl;
+ int retval;
+
+ D(("called."));
+
+ ctrl = _set_ctrl(pamh, flags, NULL, argc, argv);
+
+ retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
+ if (user_name == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "close_session - error recovering username");
+ return PAM_SESSION_ERR; /* How did we get authenticated with
+ no username?! */
+ }
+ retval = pam_get_item(pamh, PAM_SERVICE, (void *) &service);
+ if (service == NULL || retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh,
+ "close_session - error recovering service");
+ return PAM_SESSION_ERR;
+ }
+ _log_err(LOG_INFO, pamh, "session closed for user %s"
+ ,user_name);
-int pam_sm_open_session( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv )
-{
- return _pam_unix_open_session( pamh, flags, argc, argv ) ;
+ return PAM_SUCCESS;
}
-int pam_sm_close_session(pam_handle_t *pamh, int flags,
- int argc, const char **argv)
-{
- return _pam_unix_close_session( pamh, flags, argc, argv ) ;
-}
+/* static module data */
+#ifdef PAM_STATIC
+struct pam_module _pam_unix_session_modstruct = {
+ "pam_unix_session",
+ NULL,
+ NULL,
+ NULL,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ NULL,
+};
+#endif
diff --git a/contrib/libpam/modules/pam_unix/support.c b/contrib/libpam/modules/pam_unix/support.c
index a2fafcd2c13e..f7d221f18006 100644
--- a/contrib/libpam/modules/pam_unix/support.c
+++ b/contrib/libpam/modules/pam_unix/support.c
@@ -1,152 +1,882 @@
/*
- * $Header: /home/morgan/pam/Linux-PAM-0.53/modules/pam_unix/RCS/support.c,v 1.1 1996/11/09 19:44:35 morgan Exp $
+ * $Id: support.c,v 1.8 2001/02/11 06:33:53 agmorgan Exp $
+ *
+ * Copyright information at end of file.
*/
-
+
+#define _BSD_SOURCE
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <string.h>
+#include <malloc.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <limits.h>
+#include <utmp.h>
+
+#include <security/_pam_macros.h>
+#include <security/pam_modules.h>
+
+#include "md5.h"
+#include "support.h"
+
+extern char *crypt(const char *key, const char *salt);
+extern char *bigcrypt(const char *key, const char *salt);
+
+/* syslogging function for errors and other information */
+
+void _log_err(int err, pam_handle_t *pamh, const char *format,...)
+{
+ char *service = NULL;
+ char logname[256];
+ va_list args;
+
+ pam_get_item(pamh, PAM_SERVICE, (const void **) &service);
+ if (service) {
+ strncpy(logname, service, sizeof(logname));
+ logname[sizeof(logname) - 1 - strlen("(pam_unix)")] = '\0';
+ strncat(logname, "(pam_unix)", strlen("(pam_unix)"));
+ } else {
+ strncpy(logname, "pam_unix", sizeof(logname) - 1);
+ }
+
+ va_start(args, format);
+ openlog(logname, LOG_CONS | LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+/* this is a front-end for module-application conversations */
+
+static int converse(pam_handle_t * pamh, int ctrl, int nargs
+ ,struct pam_message **message
+ ,struct pam_response **response)
+{
+ int retval;
+ struct pam_conv *conv;
+
+ D(("begin to converse"));
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv);
+ if (retval == PAM_SUCCESS) {
+
+ retval = conv->conv(nargs, (const struct pam_message **) message
+ ,response, conv->appdata_ptr);
+
+ D(("returned from application's conversation function"));
+
+ if (retval != PAM_SUCCESS && on(UNIX_DEBUG, ctrl)) {
+ _log_err(LOG_DEBUG, pamh, "conversation failure [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+ } else if (retval != PAM_CONV_AGAIN) {
+ _log_err(LOG_ERR, pamh
+ ,"couldn't obtain coversation function [%s]"
+ ,pam_strerror(pamh, retval));
+ }
+ D(("ready to return from module conversation"));
+
+ return retval; /* propagate error status */
+}
+
+int _make_remark(pam_handle_t * pamh, unsigned int ctrl
+ ,int type, const char *text)
+{
+ int retval = PAM_SUCCESS;
+
+ if (off(UNIX__QUIET, ctrl)) {
+ struct pam_message *pmsg[1], msg[1];
+ struct pam_response *resp;
+
+ pmsg[0] = &msg[0];
+ msg[0].msg = text;
+ msg[0].msg_style = type;
+
+ resp = NULL;
+ retval = converse(pamh, ctrl, 1, pmsg, &resp);
+
+ if (resp) {
+ _pam_drop_reply(resp, 1);
+ }
+ }
+ return retval;
+}
+
+ /*
+ * Beacause getlogin() is braindead and sometimes it just
+ * doesn't work, we reimplement it here.
+ */
+char *PAM_getlogin(void)
+{
+ struct utmp *ut, line;
+ char *curr_tty, *retval;
+ static char curr_user[sizeof(ut->ut_user) + 4];
+
+ retval = NULL;
+
+ curr_tty = ttyname(0);
+ if (curr_tty != NULL) {
+ D(("PAM_getlogin ttyname: %s", curr_tty));
+ curr_tty += 5;
+ setutent();
+ strncpy(line.ut_line, curr_tty, sizeof line.ut_line);
+ if ((ut = getutline(&line)) != NULL) {
+ strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
+ retval = curr_user;
+ }
+ endutent();
+ }
+ D(("PAM_getlogin retval: %s", retval));
+
+ return retval;
+}
+
/*
- * Copyright Andrew Morgan, 1996. All rights reserved.
- * Modified by Alexander O. Yuriev
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, and the entire permission notice in its entirety,
- * including the disclaimer of warranties.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote
- * products derived from this software without specific prior
- * written permission.
- *
- * ALTERNATIVELY, this product may be distributed under the terms of
- * the GNU Public License, in which case the provisions of the GPL are
- * required INSTEAD OF the above restrictions. (This clause is
- * necessary due to a potential bad interaction between the GPL and
- * the restrictions contained in a BSD-style copyright.)
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
- * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
- * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
+ * set the control flags for the UNIX module.
*/
+int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int argc,
+ const char **argv)
+{
+ unsigned int ctrl;
+
+ D(("called."));
+
+ ctrl = UNIX_DEFAULTS; /* the default selection of options */
+
+ /* set some flags manually */
+
+ if (getuid() == 0 && !(flags & PAM_CHANGE_EXPIRED_AUTHTOK)) {
+ D(("IAMROOT"));
+ set(UNIX__IAMROOT, ctrl);
+ }
+ if (flags & PAM_UPDATE_AUTHTOK) {
+ D(("UPDATE_AUTHTOK"));
+ set(UNIX__UPDATE, ctrl);
+ }
+ if (flags & PAM_PRELIM_CHECK) {
+ D(("PRELIM_CHECK"));
+ set(UNIX__PRELIM, ctrl);
+ }
+ if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
+ D(("DISALLOW_NULL_AUTHTOK"));
+ set(UNIX__NONULL, ctrl);
+ }
+ if (flags & PAM_SILENT) {
+ D(("SILENT"));
+ set(UNIX__QUIET, ctrl);
+ }
+ /* now parse the arguments to this module */
+
+ while (argc-- > 0) {
+ int j;
+
+ D(("pam_unix arg: %s", *argv));
+
+ for (j = 0; j < UNIX_CTRLS_; ++j) {
+ if (unix_args[j].token
+ && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) {
+ break;
+ }
+ }
+
+ if (j >= UNIX_CTRLS_) {
+ _log_err(LOG_ERR, pamh,
+ "unrecognized option [%s]", *argv);
+ } else {
+ ctrl &= unix_args[j].mask; /* for turning things off */
+ ctrl |= unix_args[j].flag; /* for turning things on */
+
+ if (remember != NULL) {
+ if (j == UNIX_REMEMBER_PASSWD) {
+ *remember = strtol(*argv + 9, NULL, 10);
+ if ((*remember == LONG_MIN) || (*remember == LONG_MAX))
+ *remember = -1;
+ if (*remember > 400)
+ *remember = 400;
+ }
+ }
+ }
+
+ ++argv; /* step to next argument */
+ }
+
+ /* auditing is a more sensitive version of debug */
+
+ if (on(UNIX_AUDIT, ctrl)) {
+ set(UNIX_DEBUG, ctrl);
+ }
+ /* return the set of flags */
+
+ D(("done."));
+ return ctrl;
+}
+
+static void _cleanup(pam_handle_t * pamh, void *x, int error_status)
+{
+ _pam_delete(x);
+}
+
+/* ************************************************************** *
+ * Useful non-trivial functions *
+ * ************************************************************** */
+
+ /*
+ * the following is used to keep track of the number of times a user fails
+ * to authenticate themself.
+ */
+
+#define FAIL_PREFIX "-UN*X-FAIL-"
+#define UNIX_MAX_RETRIES 3
+
+struct _pam_failed_auth {
+ char *user; /* user that's failed to be authenticated */
+ char *name; /* attempt from user with name */
+ int uid; /* uid of calling user */
+ int euid; /* euid of calling process */
+ int count; /* number of failures so far */
+};
+
+#ifndef PAM_DATA_REPLACE
+#error "Need to get an updated libpam 0.52 or better"
+#endif
+
+static void _cleanup_failures(pam_handle_t * pamh, void *fl, int err)
+{
+ int quiet;
+ const char *service = NULL;
+ const char *ruser = NULL;
+ const char *rhost = NULL;
+ const char *tty = NULL;
+ struct _pam_failed_auth *failure;
+
+ D(("called"));
+
+ quiet = err & PAM_DATA_SILENT; /* should we log something? */
+ err &= PAM_DATA_REPLACE; /* are we just replacing data? */
+ failure = (struct _pam_failed_auth *) fl;
+
+ if (failure != NULL) {
+
+ if (!quiet && !err) { /* under advisement from Sun,may go away */
+
+ /* log the number of authentication failures */
+ if (failure->count > 1) {
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ (const void **)&service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ (const void **)&ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ (const void **)&rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ (const void **)&tty);
+ _log_err(LOG_NOTICE, pamh,
+ "%d more authentication failure%s; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ failure->count - 1, failure->count == 2 ? "" : "s",
+ failure->name, failure->uid, failure->euid,
+ tty ? tty : "", ruser ? ruser : "",
+ rhost ? rhost : "",
+ (failure->user && failure->user[0] != '\0')
+ ? " user=" : "", failure->user
+ );
+
+ if (failure->count > UNIX_MAX_RETRIES) {
+ _log_err(LOG_ALERT, pamh
+ ,"service(%s) ignoring max retries; %d > %d"
+ ,service == NULL ? "**unknown**" : service
+ ,failure->count
+ ,UNIX_MAX_RETRIES);
+ }
+ }
+ }
+ _pam_delete(failure->user); /* tidy up */
+ _pam_delete(failure->name); /* tidy up */
+ free(failure);
+ }
+}
+
/*
- * $Log: support.c,v $
- * Revision 1.1 1996/11/09 19:44:35 morgan
- * Initial revision
- *
- * Revision 1.1 1996/04/17 01:11:08 alex
- * Initial revision
+ * _unix_blankpasswd() is a quick check for a blank password
*
+ * returns TRUE if user does not have a password
+ * - to avoid prompting for one in such cases (CG)
*/
-
-#include <stdlib.h> /* define NULL */
-#ifndef LINUX
+int _unix_blankpasswd(unsigned int ctrl, const char *name)
+{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ int retval;
- #include <security/pam_appl.h>
+ D(("called"));
-#endif /* LINUX */
+ /*
+ * This function does not have to be too smart if something goes
+ * wrong, return FALSE and let this case to be treated somewhere
+ * else (CG)
+ */
-#include <security/pam_modules.h>
+ if (on(UNIX__NONULL, ctrl))
+ return 0; /* will fail but don't let on yet */
+
+ /* UNIX passwords area */
+ pwd = getpwnam(name); /* Get password file entry... */
+
+ if (pwd != NULL) {
+ if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwd->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwd->pw_uid ) == -1)
+ /* Will fail elsewhere. */
+ return 0;
+ }
+ }
+
+ spwdent = getspnam( name );
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+ } else if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ spwdent = getspnam(name);
+ }
+ if (spwdent)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ salt = x_strdup(pwd->pw_passwd);
+ }
+ /* Does this user have a password? */
+ if (salt == NULL) {
+ retval = 0;
+ } else {
+ if (strlen(salt) == 0)
+ retval = 1;
+ else
+ retval = 0;
+ }
+ /* tidy up */
-#ifndef NDEBUG
+ if (salt)
+ _pam_delete(salt);
- #include <syslog.h>
+ return retval;
+}
-#endif /* NDEBUG */
+/*
+ * verify the password of a user
+ */
+
+#include <sys/types.h>
+#include <sys/wait.h>
+
+static int _unix_run_helper_binary(pam_handle_t *pamh, const char *passwd,
+ unsigned int ctrl, const char *user)
+{
+ int retval, child, fds[2];
+ D(("called."));
+ /* create a pipe for the password */
+ if (pipe(fds) != 0) {
+ D(("could not make pipe"));
+ return PAM_AUTH_ERR;
+ }
-/* Phototype declarations */
+ /* fork */
+ child = fork();
+ if (child == 0) {
+ static char *envp[] = { NULL };
+ char *args[] = { NULL, NULL, NULL };
-int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response );
+ /* XXX - should really tidy up PAM here too */
-int _set_auth_tok( pam_handle_t *pamh,
- int flags,
- int argc,
- const char **argv );
+ /* reopen stdin as pipe */
+ close(fds[1]);
+ dup2(fds[0], STDIN_FILENO);
-/* Implementation */
+ /* exec binary helper */
+ args[0] = x_strdup(CHKPWD_HELPER);
+ args[1] = x_strdup(user);
-int converse( pam_handle_t *pamh,
- int nargs,
- struct pam_message **message,
- struct pam_response **response )
+ execve(CHKPWD_HELPER, args, envp);
+ /* should not get here: exit with error */
+ D(("helper binary is not available"));
+ exit(PAM_AUTHINFO_UNAVAIL);
+ } else if (child > 0) {
+ /* wait for child */
+ /* if the stored password is NULL */
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ write(fds[1], "nullok\0\0", 8);
+ } else {
+ write(fds[1], "nonull\0\0", 8);
+ }
+ if (passwd != NULL) { /* send the password to the child */
+ write(fds[1], passwd, strlen(passwd)+1);
+ passwd = NULL;
+ } else {
+ write(fds[1], "", 1); /* blank password */
+ }
+ close(fds[0]); /* close here to avoid possible SIGPIPE above */
+ close(fds[1]);
+ (void) waitpid(child, &retval, 0); /* wait for helper to complete */
+ retval = (retval == 0) ? PAM_SUCCESS:PAM_AUTH_ERR;
+ } else {
+ D(("fork failed"));
+ retval = PAM_AUTH_ERR;
+ }
+
+ D(("returning %d", retval));
+ return retval;
+}
+
+int _unix_verify_password(pam_handle_t * pamh, const char *name
+ ,const char *p, unsigned int ctrl)
{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ char *pp = NULL;
+ char *data_name;
int retval;
- struct pam_conv *conv;
- retval = pam_get_item( pamh, PAM_CONV, (const void **) &conv ) ;
- if ( retval == PAM_SUCCESS )
- {
- retval = conv->conv( nargs,
- ( const struct pam_message ** ) message,
- response,
- conv->appdata_ptr );
- }
+ D(("called"));
+
+#ifdef HAVE_PAM_FAIL_DELAY
+ if (off(UNIX_NODELAY, ctrl)) {
+ D(("setting delay"));
+ (void) pam_fail_delay(pamh, 2000000); /* 2 sec delay for on failure */
+ }
+#endif
+
+ /* locate the entry for this user */
+
+ D(("locating user's record"));
+
+ /* UNIX passwords area */
+ pwd = getpwnam(name); /* Get password file entry... */
+
+ if (pwd != NULL) {
+ if (strcmp( pwd->pw_passwd, "*NP*" ) == 0)
+ { /* NIS+ */
+ uid_t save_euid, save_uid;
+
+ save_euid = geteuid();
+ save_uid = getuid();
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_euid, save_uid );
+ else {
+ setreuid( 0, -1 );
+ if (setreuid( -1, pwd->pw_uid ) == -1) {
+ setreuid( -1, 0 );
+ setreuid( 0, -1 );
+ if(setreuid( -1, pwd->pw_uid ) == -1)
+ return PAM_CRED_INSUFFICIENT;
+ }
+ }
+
+ spwdent = getspnam( name );
+ if (save_uid == pwd->pw_uid)
+ setreuid( save_uid, save_euid );
+ else {
+ if (setreuid( -1, 0 ) == -1)
+ setreuid( save_uid, -1 );
+ setreuid( -1, save_euid );
+ }
+ } else if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ spwdent = getspnam(name);
+ }
+ if (spwdent)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ salt = x_strdup(pwd->pw_passwd);
+ }
+
+ data_name = (char *) malloc(sizeof(FAIL_PREFIX) + strlen(name));
+ if (data_name == NULL) {
+ _log_err(LOG_CRIT, pamh, "no memory for data-name");
+ } else {
+ strcpy(data_name, FAIL_PREFIX);
+ strcpy(data_name + sizeof(FAIL_PREFIX) - 1, name);
+ }
+
+ retval = PAM_SUCCESS;
+ if (pwd == NULL || salt == NULL || !strcmp(salt, "x")) {
+ if (geteuid()) {
+ /* we are not root perhaps this is the reason? Run helper */
+ D(("running helper binary"));
+ retval = _unix_run_helper_binary(pamh, p, ctrl, name);
+ if (pwd == NULL && !on(UNIX_AUDIT,ctrl)
+ && retval != PAM_SUCCESS)
+ {
+ name = NULL;
+ }
+ } else {
+ D(("user's record unavailable"));
+ if (on(UNIX_AUDIT, ctrl)) {
+ /* this might be a typo and the user has given a password
+ instead of a username. Careful with this. */
+ _log_err(LOG_ALERT, pamh,
+ "check pass; user (%s) unknown", name);
+ } else {
+ name = NULL;
+ _log_err(LOG_ALERT, pamh,
+ "check pass; user unknown");
+ }
+ p = NULL;
+ retval = PAM_AUTHINFO_UNAVAIL;
+ }
+ } else {
+ if (!strlen(salt)) {
+ /* the stored password is NULL */
+ if (off(UNIX__NONULL, ctrl)) { /* this means we've succeeded */
+ D(("user has empty password - access granted"));
+ retval = PAM_SUCCESS;
+ } else {
+ D(("user has empty password - access denied"));
+ retval = PAM_AUTH_ERR;
+ }
+ } else if (!p) {
+ retval = PAM_AUTH_ERR;
+ } else {
+ if (!strncmp(salt, "$1$", 3)) {
+ pp = Goodcrypt_md5(p, salt);
+ if (strcmp(pp, salt) != 0) {
+ pp = Brokencrypt_md5(p, salt);
+ }
+ } else {
+ pp = bigcrypt(p, salt);
+ }
+ p = NULL; /* no longer needed here */
+
+ /* the moment of truth -- do we agree with the password? */
+ D(("comparing state of pp[%s] and salt[%s]", pp, salt));
+
+ if (strcmp(pp, salt) == 0) {
+ retval = PAM_SUCCESS;
+ } else {
+ retval = PAM_AUTH_ERR;
+ }
+ }
+ }
+
+ if (retval == PAM_SUCCESS) {
+ if (data_name) /* reset failures */
+ pam_set_data(pamh, data_name, NULL, _cleanup_failures);
+ } else {
+ if (data_name != NULL) {
+ struct _pam_failed_auth *new = NULL;
+ const struct _pam_failed_auth *old = NULL;
+
+ /* get a failure recorder */
+
+ new = (struct _pam_failed_auth *)
+ malloc(sizeof(struct _pam_failed_auth));
+
+ if (new != NULL) {
+
+ new->user = x_strdup(name ? name : "");
+ new->uid = getuid();
+ new->euid = geteuid();
+ new->name = x_strdup(PAM_getlogin()? PAM_getlogin() : "");
+
+ /* any previous failures for this user ? */
+ pam_get_data(pamh, data_name, (const void **) &old);
+
+ if (old != NULL) {
+ new->count = old->count + 1;
+ if (new->count >= UNIX_MAX_RETRIES) {
+ retval = PAM_MAXTRIES;
+ }
+ } else {
+ const char *service=NULL;
+ const char *ruser=NULL;
+ const char *rhost=NULL;
+ const char *tty=NULL;
+
+ (void) pam_get_item(pamh, PAM_SERVICE,
+ (const void **)&service);
+ (void) pam_get_item(pamh, PAM_RUSER,
+ (const void **)&ruser);
+ (void) pam_get_item(pamh, PAM_RHOST,
+ (const void **)&rhost);
+ (void) pam_get_item(pamh, PAM_TTY,
+ (const void **)&tty);
+
+ _log_err(LOG_NOTICE, pamh,
+ "authentication failure; "
+ "logname=%s uid=%d euid=%d "
+ "tty=%s ruser=%s rhost=%s "
+ "%s%s",
+ new->name, new->uid, new->euid,
+ tty ? tty : "",
+ ruser ? ruser : "",
+ rhost ? rhost : "",
+ (new->user && new->user[0] != '\0')
+ ? " user=" : "",
+ new->user
+ );
+ new->count = 1;
+ }
+
+ pam_set_data(pamh, data_name, new, _cleanup_failures);
+
+ } else {
+ _log_err(LOG_CRIT, pamh,
+ "no memory for failure recorder");
+ }
+ }
+ }
+
+ if (data_name)
+ _pam_delete(data_name);
+ if (salt)
+ _pam_delete(salt);
+ if (pp)
+ _pam_overwrite(pp);
+
+ D(("done [%d].", retval));
+
return retval;
}
-/***************************************************************************/
-/* prompt user for a using conversation calls */
-/***************************************************************************/
+/*
+ * obtain a password from the user
+ */
-int _set_auth_tok( pam_handle_t *pamh,
- int flags, int argc,
- const char **argv )
+int _unix_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char *data_name
+ ,const char **pass)
{
- int retval;
- char *p;
-
- struct pam_message msg[1],*pmsg[1];
- struct pam_response *resp;
+ int authtok_flag;
+ int retval;
+ const char *item;
+ char *token;
+
+ D(("called"));
+
+ /*
+ * make sure nothing inappropriate gets returned
+ */
+
+ *pass = token = NULL;
+
+ /*
+ * which authentication token are we getting?
+ */
+
+ authtok_flag = on(UNIX__OLD_PASSWD, ctrl) ? PAM_OLDAUTHTOK : PAM_AUTHTOK;
+
+ /*
+ * should we obtain the password from a PAM item ?
+ */
- /* set up conversation call */
+ if (on(UNIX_TRY_FIRST_PASS, ctrl) || on(UNIX_USE_FIRST_PASS, ctrl)) {
+ retval = pam_get_item(pamh, authtok_flag, (const void **) &item);
+ if (retval != PAM_SUCCESS) {
+ /* very strange. */
+ _log_err(LOG_ALERT, pamh
+ ,"pam_get_item returned error to unix-read-password"
+ );
+ return retval;
+ } else if (item != NULL) { /* we have a password! */
+ *pass = item;
+ item = NULL;
+ return PAM_SUCCESS;
+ } else if (on(UNIX_USE_FIRST_PASS, ctrl)) {
+ return PAM_AUTHTOK_RECOVER_ERR; /* didn't work */
+ } else if (on(UNIX_USE_AUTHTOK, ctrl)
+ && off(UNIX__OLD_PASSWD, ctrl)) {
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+ }
+ /*
+ * getting here implies we will have to get the password from the
+ * user directly.
+ */
- pmsg[0] = &msg[0];
- msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
- msg[0].msg = "Password: ";
- resp = NULL;
+ {
+ struct pam_message msg[3], *pmsg[3];
+ struct pam_response *resp;
+ int i, replies;
- if ( ( retval = converse( pamh, 1 , pmsg, &resp ) ) != PAM_SUCCESS )
+ /* prepare to converse */
+
+ if (comment != NULL && off(UNIX__QUIET, ctrl)) {
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_TEXT_INFO;
+ msg[0].msg = comment;
+ i = 1;
+ } else {
+ i = 0;
+ }
+
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = prompt1;
+ replies = 1;
+
+ if (prompt2 != NULL) {
+ pmsg[i] = &msg[i];
+ msg[i].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[i++].msg = prompt2;
+ ++replies;
+ }
+ /* so call the conversation expecting i responses */
+ resp = NULL;
+ retval = converse(pamh, ctrl, i, pmsg, &resp);
+
+ if (resp != NULL) {
+
+ /* interpret the response */
+
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+
+ token = x_strdup(resp[i - replies].resp);
+ if (token != NULL) {
+ if (replies == 2) {
+
+ /* verify that password entered correctly */
+ if (!resp[i - 1].resp
+ || strcmp(token, resp[i - 1].resp)) {
+ _pam_delete(token); /* mistyped */
+ retval = PAM_AUTHTOK_RECOVER_ERR;
+ _make_remark(pamh, ctrl
+ ,PAM_ERROR_MSG, MISTYPED_PASS);
+ }
+ }
+ } else {
+ _log_err(LOG_NOTICE, pamh
+ ,"could not recover authentication token");
+ }
+
+ }
+ /*
+ * tidy up the conversation (resp_retcode) is ignored
+ * -- what is it for anyway? AGM
+ */
+
+ _pam_drop_reply(resp, i);
+
+ } else {
+ retval = (retval == PAM_SUCCESS)
+ ? PAM_AUTHTOK_RECOVER_ERR : retval;
+ }
+ }
+
+ if (retval != PAM_SUCCESS) {
+ if (on(UNIX_DEBUG, ctrl))
+ _log_err(LOG_DEBUG, pamh,
+ "unable to obtain a password");
return retval;
+ }
+ /* 'token' is the entered password */
+
+ if (off(UNIX_NOT_SET_PASS, ctrl)) {
+
+ /* we store this password as an item */
+
+ retval = pam_set_item(pamh, authtok_flag, token);
+ _pam_delete(token); /* clean it up */
+ if (retval != PAM_SUCCESS
+ || (retval = pam_get_item(pamh, authtok_flag
+ ,(const void **) &item))
+ != PAM_SUCCESS) {
+
+ _log_err(LOG_CRIT, pamh, "error manipulating password");
+ return retval;
+
+ }
+ } else {
+ /*
+ * then store it as data specific to this module. pam_end()
+ * will arrange to clean it up.
+ */
+
+ retval = pam_set_data(pamh, data_name, (void *) token, _cleanup);
+ if (retval != PAM_SUCCESS) {
+ _log_err(LOG_CRIT, pamh
+ ,"error manipulating password data [%s]"
+ ,pam_strerror(pamh, retval));
+ _pam_delete(token);
+ return retval;
+ }
+ item = token;
+ token = NULL; /* break link to password */
+ }
+
+ *pass = item;
+ item = NULL; /* break link to password */
- if ( resp )
- {
- if ( ( flags & PAM_DISALLOW_NULL_AUTHTOK ) &&
- resp[0].resp == NULL )
- {
- free( resp );
- return PAM_AUTH_ERR;
- }
-
- p = resp[ 0 ].resp;
-
- /* This could be a memory leak. If resp[0].resp
- is malloc()ed, then it has to be free()ed!
- -- alex
- */
-
- resp[ 0 ].resp = NULL;
-
- }
- else
- return PAM_CONV_ERR;
-
- free( resp );
- pam_set_item( pamh, PAM_AUTHTOK, p );
return PAM_SUCCESS;
}
+
+/* ****************************************************************** *
+ * Copyright (c) Jan Rêkorajski 1999.
+ * Copyright (c) Andrew G. Morgan 1996-8.
+ * Copyright (c) Alex O. Yuriev, 1996.
+ * Copyright (c) Cristian Gafton 1996.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/contrib/libpam/modules/pam_unix/support.h b/contrib/libpam/modules/pam_unix/support.h
new file mode 100644
index 000000000000..80f0b405d8bb
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/support.h
@@ -0,0 +1,144 @@
+/*
+ * $Id: support.h,v 1.3 2000/12/20 05:15:05 vorlon Exp $
+ */
+
+#ifndef _PAM_UNIX_SUPPORT_H
+#define _PAM_UNIX_SUPPORT_H
+
+
+/*
+ * here is the string to inform the user that the new passwords they
+ * typed were not the same.
+ */
+
+#define MISTYPED_PASS "Sorry, passwords do not match"
+
+/* type definition for the control options */
+
+typedef struct {
+ const char *token;
+ unsigned int mask; /* shall assume 32 bits of flags */
+ unsigned int flag;
+} UNIX_Ctrls;
+
+/*
+ * macro to determine if a given flag is on
+ */
+
+#define on(x,ctrl) (unix_args[x].flag & ctrl)
+
+/*
+ * macro to determine that a given flag is NOT on
+ */
+
+#define off(x,ctrl) (!on(x,ctrl))
+
+/*
+ * macro to turn on/off a ctrl flag manually
+ */
+
+#define set(x,ctrl) (ctrl = ((ctrl)&unix_args[x].mask)|unix_args[x].flag)
+#define unset(x,ctrl) (ctrl &= ~(unix_args[x].flag))
+
+/* the generic mask */
+
+#define _ALL_ON_ (~0U)
+
+/* end of macro definitions definitions for the control flags */
+
+/* ****************************************************************** *
+ * ctrl flags proper..
+ */
+
+/*
+ * here are the various options recognized by the unix module. They
+ * are enumerated here and then defined below. Internal arguments are
+ * given NULL tokens.
+ */
+
+#define UNIX__OLD_PASSWD 0 /* internal */
+#define UNIX__VERIFY_PASSWD 1 /* internal */
+#define UNIX__IAMROOT 2 /* internal */
+
+#define UNIX_AUDIT 3 /* print more things than debug..
+ some information may be sensitive */
+#define UNIX_USE_FIRST_PASS 4
+#define UNIX_TRY_FIRST_PASS 5
+#define UNIX_NOT_SET_PASS 6 /* don't set the AUTHTOK items */
+
+#define UNIX__PRELIM 7 /* internal */
+#define UNIX__UPDATE 8 /* internal */
+#define UNIX__NONULL 9 /* internal */
+#define UNIX__QUIET 10 /* internal */
+#define UNIX_USE_AUTHTOK 11 /* insist on reading PAM_AUTHTOK */
+#define UNIX_SHADOW 12 /* signal shadow on */
+#define UNIX_MD5_PASS 13 /* force the use of MD5 passwords */
+#define UNIX__NULLOK 14 /* Null token ok */
+#define UNIX_DEBUG 15 /* send more info to syslog(3) */
+#define UNIX_NODELAY 16 /* admin does not want a fail-delay */
+#define UNIX_NIS 17 /* wish to use NIS for pwd */
+#define UNIX_BIGCRYPT 18 /* use DEC-C2 crypt()^x function */
+#define UNIX_LIKE_AUTH 19 /* need to auth for setcred to work */
+#define UNIX_REMEMBER_PASSWD 20 /* Remember N previous passwords */
+/* -------------- */
+#define UNIX_CTRLS_ 21 /* number of ctrl arguments defined */
+
+
+static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
+{
+/* symbol token name ctrl mask ctrl *
+ * ----------------------- ------------------- --------------------- -------- */
+
+/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01},
+/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02},
+/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04},
+/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010},
+/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020},
+/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040},
+/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100},
+/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200},
+/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400},
+/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000},
+/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000},
+/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000},
+/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000},
+/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0400000), 020000},
+/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0},
+/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000},
+/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000},
+/* UNIX_NIS */ {"nis", _ALL_ON_^(010000), 0200000},
+/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(020000), 0400000},
+/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000},
+/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000},
+};
+
+#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
+
+
+/* use this to free strings. ESPECIALLY password strings */
+
+#define _pam_delete(xx) \
+{ \
+ _pam_overwrite(xx); \
+ _pam_drop(xx); \
+}
+
+extern char *PAM_getlogin(void);
+extern void _log_err(int err, pam_handle_t *pamh, const char *format,...);
+extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl
+ ,int type, const char *text);
+extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int argc,
+ const char **argv);
+extern int _unix_blankpasswd(unsigned int ctrl, const char *name);
+extern int _unix_verify_password(pam_handle_t * pamh, const char *name
+ ,const char *p, unsigned int ctrl);
+extern int _unix_read_password(pam_handle_t * pamh
+ ,unsigned int ctrl
+ ,const char *comment
+ ,const char *prompt1
+ ,const char *prompt2
+ ,const char *data_name
+ ,const char **pass);
+
+#endif /* _PAM_UNIX_SUPPORT_H */
+
diff --git a/contrib/libpam/modules/pam_unix/unix_chkpwd.c b/contrib/libpam/modules/pam_unix/unix_chkpwd.c
new file mode 100644
index 000000000000..e232e759453c
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/unix_chkpwd.c
@@ -0,0 +1,314 @@
+/*
+ * $Id: unix_chkpwd.c,v 1.3 2001/02/11 06:33:53 agmorgan Exp $
+ *
+ * This program is designed to run setuid(root) or with sufficient
+ * privilege to read all of the unix password databases. It is designed
+ * to provide a mechanism for the current user (defined by this
+ * process' uid) to verify their own password.
+ *
+ * The password is read from the standard input. The exit status of
+ * this program indicates whether the user is authenticated or not.
+ *
+ * Copyright information is located at the end of the file.
+ *
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <pwd.h>
+#include <shadow.h>
+#include <signal.h>
+
+#define MAXPASS 200 /* the maximum length of a password */
+
+#include <security/_pam_macros.h>
+
+#include "md5.h"
+
+extern char *crypt(const char *key, const char *salt);
+extern char *bigcrypt(const char *key, const char *salt);
+
+#define UNIX_PASSED 0
+#define UNIX_FAILED 1
+
+/* syslogging function for errors and other information */
+
+static void _log_err(int err, const char *format,...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog("unix_chkpwd", LOG_CONS | LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+static void su_sighandler(int sig)
+{
+ if (sig > 0) {
+ _log_err(LOG_NOTICE, "caught signal %d.", sig);
+ exit(sig);
+ }
+}
+
+static void setup_signals(void)
+{
+ struct sigaction action; /* posix signal structure */
+
+ /*
+ * Setup signal handlers
+ */
+ (void) memset((void *) &action, 0, sizeof(action));
+ action.sa_handler = su_sighandler;
+ action.sa_flags = SA_RESETHAND;
+ (void) sigaction(SIGILL, &action, NULL);
+ (void) sigaction(SIGTRAP, &action, NULL);
+ (void) sigaction(SIGBUS, &action, NULL);
+ (void) sigaction(SIGSEGV, &action, NULL);
+ action.sa_handler = SIG_IGN;
+ action.sa_flags = 0;
+ (void) sigaction(SIGTERM, &action, NULL);
+ (void) sigaction(SIGHUP, &action, NULL);
+ (void) sigaction(SIGINT, &action, NULL);
+ (void) sigaction(SIGQUIT, &action, NULL);
+}
+
+static int _unix_verify_password(const char *name, const char *p, int opt)
+{
+ struct passwd *pwd = NULL;
+ struct spwd *spwdent = NULL;
+ char *salt = NULL;
+ char *pp = NULL;
+ int retval = UNIX_FAILED;
+
+ /* UNIX passwords area */
+ setpwent();
+ pwd = getpwnam(name); /* Get password file entry... */
+ endpwent();
+ if (pwd != NULL) {
+ if (strcmp(pwd->pw_passwd, "x") == 0) {
+ /*
+ * ...and shadow password file entry for this user,
+ * if shadowing is enabled
+ */
+ setspent();
+ spwdent = getspnam(name);
+ endspent();
+ if (spwdent != NULL)
+ salt = x_strdup(spwdent->sp_pwdp);
+ else
+ pwd = NULL;
+ } else {
+ if (strcmp(pwd->pw_passwd, "*NP*") == 0) { /* NIS+ */
+ uid_t save_uid;
+
+ save_uid = geteuid();
+ seteuid(pwd->pw_uid);
+ spwdent = getspnam(name);
+ seteuid(save_uid);
+
+ salt = x_strdup(spwdent->sp_pwdp);
+ } else {
+ salt = x_strdup(pwd->pw_passwd);
+ }
+ }
+ }
+ if (pwd == NULL || salt == NULL) {
+ _log_err(LOG_ALERT, "check pass; user unknown");
+ p = NULL;
+ return retval;
+ }
+
+ if (strlen(salt) == 0)
+ return (opt == 0) ? UNIX_FAILED : UNIX_PASSED;
+
+ /* the moment of truth -- do we agree with the password? */
+ retval = UNIX_FAILED;
+ if (!strncmp(salt, "$1$", 3)) {
+ pp = Goodcrypt_md5(p, salt);
+ if (strcmp(pp, salt) == 0) {
+ retval = UNIX_PASSED;
+ } else {
+ pp = Brokencrypt_md5(p, salt);
+ if (strcmp(pp, salt) == 0)
+ retval = UNIX_PASSED;
+ }
+ } else {
+ pp = bigcrypt(p, salt);
+ if (strcmp(pp, salt) == 0) {
+ retval = UNIX_PASSED;
+ }
+ }
+ p = NULL; /* no longer needed here */
+
+ /* clean up */
+ {
+ char *tp = pp;
+ if (pp != NULL) {
+ while (tp && *tp)
+ *tp++ = '\0';
+ }
+ pp = tp = NULL;
+ }
+
+ return retval;
+}
+
+static char *getuidname(uid_t uid)
+{
+ struct passwd *pw;
+ static char username[32];
+
+ pw = getpwuid(uid);
+ if (pw == NULL)
+ return NULL;
+
+ memset(username, 0, 32);
+ strncpy(username, pw->pw_name, 32);
+ username[31] = '\0';
+
+ return username;
+}
+
+int main(int argc, char *argv[])
+{
+ char pass[MAXPASS + 1];
+ char option[8];
+ int npass, opt;
+ int force_failure = 0;
+ int retval = UNIX_FAILED;
+ char *user;
+
+ /*
+ * Catch or ignore as many signal as possible.
+ */
+ setup_signals();
+
+ /*
+ * we establish that this program is running with non-tty stdin.
+ * this is to discourage casual use. It does *NOT* prevent an
+ * intruder from repeatadly running this program to determine the
+ * password of the current user (brute force attack, but one for
+ * which the attacker must already have gained access to the user's
+ * account).
+ */
+
+ if (isatty(STDIN_FILENO)) {
+
+ _log_err(LOG_NOTICE
+ ,"inappropriate use of Unix helper binary [UID=%d]"
+ ,getuid());
+ fprintf(stderr
+ ,"This binary is not designed for running in this way\n"
+ "-- the system administrator has been informed\n");
+ sleep(10); /* this should discourage/annoy the user */
+ return UNIX_FAILED;
+ }
+
+ /*
+ * determine the current user's name is
+ */
+ user = getuidname(getuid());
+ if (argc == 2) {
+ /* if the caller specifies the username, verify that user
+ matches it */
+ if (strcmp(user, argv[1])) {
+ force_failure = 1;
+ }
+ }
+
+ /* read the nollok/nonull option */
+
+ npass = read(STDIN_FILENO, option, 8);
+
+ if (npass < 0) {
+ _log_err(LOG_DEBUG, "no option supplied");
+ return UNIX_FAILED;
+ } else {
+ option[7] = '\0';
+ if (strncmp(option, "nullok", 8) == 0)
+ opt = 1;
+ else
+ opt = 0;
+ }
+
+ /* read the password from stdin (a pipe from the pam_unix module) */
+
+ npass = read(STDIN_FILENO, pass, MAXPASS);
+
+ if (npass < 0) { /* is it a valid password? */
+
+ _log_err(LOG_DEBUG, "no password supplied");
+
+ } else if (npass >= MAXPASS) {
+
+ _log_err(LOG_DEBUG, "password too long");
+
+ } else {
+ if (npass == 0) {
+ /* the password is NULL */
+
+ retval = _unix_verify_password(user, NULL, opt);
+
+ } else {
+ /* does pass agree with the official one? */
+
+ pass[npass] = '\0'; /* NUL terminate */
+ retval = _unix_verify_password(user, pass, opt);
+
+ }
+ }
+
+ memset(pass, '\0', MAXPASS); /* clear memory of the password */
+
+ /* return pass or fail */
+
+ if ((retval != UNIX_PASSED) || force_failure) {
+ return UNIX_FAILED;
+ } else {
+ return UNIX_PASSED;
+ }
+}
+
+/*
+ * Copyright (c) Andrew G. Morgan, 1996. All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/contrib/libpam/modules/pam_unix/yppasswd.h b/contrib/libpam/modules/pam_unix/yppasswd.h
new file mode 100644
index 000000000000..6b414be09a57
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/yppasswd.h
@@ -0,0 +1,51 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#ifndef _YPPASSWD_H_
+#define _YPPASSWD_H_
+
+#define YPPASSWDPROG ((u_long)100009)
+#define YPPASSWDVERS ((u_long)1)
+#define YPPASSWDPROC_UPDATE ((u_long)1)
+
+/*
+ * The password struct passed by the update call. I renamed it to
+ * xpasswd to avoid a type clash with the one defined in <pwd.h>.
+ */
+#ifndef __sgi
+typedef struct xpasswd {
+ char *pw_name;
+ char *pw_passwd;
+ int pw_uid;
+ int pw_gid;
+ char *pw_gecos;
+ char *pw_dir;
+ char *pw_shell;
+} xpasswd;
+
+#else
+#include <pwd.h>
+typedef struct xpasswd xpasswd;
+#endif
+
+/* The updated password information, plus the old password.
+ */
+typedef struct yppasswd {
+ char *oldpass;
+ xpasswd newpw;
+} yppasswd;
+
+/* XDR encoding/decoding routines */
+bool_t xdr_xpasswd(XDR * xdrs, xpasswd * objp);
+bool_t xdr_yppasswd(XDR * xdrs, yppasswd * objp);
+
+#endif /* _YPPASSWD_H_ */
diff --git a/contrib/libpam/modules/pam_unix/yppasswd_xdr.c b/contrib/libpam/modules/pam_unix/yppasswd_xdr.c
new file mode 100644
index 000000000000..b1a60b4ce11e
--- /dev/null
+++ b/contrib/libpam/modules/pam_unix/yppasswd_xdr.c
@@ -0,0 +1,38 @@
+/*
+ * yppasswdd
+ * Copyright 1994, 1995, 1996 Olaf Kirch, <okir@monad.swb.de>
+ *
+ * This program is covered by the GNU General Public License, version 2.
+ * It is provided in the hope that it is useful. However, the author
+ * disclaims ALL WARRANTIES, expressed or implied. See the GPL for details.
+ *
+ * This file was generated automatically by rpcgen from yppasswd.x, and
+ * editied manually.
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <rpc/rpc.h>
+#include <rpcsvc/yp_prot.h>
+#include <rpcsvc/ypclnt.h>
+#include "yppasswd.h"
+
+bool_t
+xdr_xpasswd(XDR * xdrs, xpasswd * objp)
+{
+ return xdr_string(xdrs, &objp->pw_name, ~0)
+ && xdr_string(xdrs, &objp->pw_passwd, ~0)
+ && xdr_int(xdrs, &objp->pw_uid)
+ && xdr_int(xdrs, &objp->pw_gid)
+ && xdr_string(xdrs, &objp->pw_gecos, ~0)
+ && xdr_string(xdrs, &objp->pw_dir, ~0)
+ && xdr_string(xdrs, &objp->pw_shell, ~0);
+}
+
+
+bool_t
+xdr_yppasswd(XDR * xdrs, yppasswd * objp)
+{
+ return xdr_string(xdrs, &objp->oldpass, ~0)
+ && xdr_xpasswd(xdrs, &objp->newpw);
+}
diff --git a/contrib/libpam/modules/pam_userdb/Makefile b/contrib/libpam/modules/pam_userdb/Makefile
new file mode 100644
index 000000000000..ebdcff9cd335
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/Makefile
@@ -0,0 +1,35 @@
+#
+# This Makefile controls a build process of $(TITLE) module for
+# Linux-PAM. You should not modify this Makefile (unless you know
+# what you are doing!).
+
+# $Id: Makefile,v 1.4 2001/02/18 03:03:31 agmorgan Exp $
+# Created by Cristian Gafton <gafton@redhat.com>
+
+include ../../Make.Rules
+
+TITLE=pam_userdb
+
+ifeq ($(HAVE_NDBM_H),yes)
+ WHICH_DB=ndbm
+ MODULE_SIMPLE_EXTRALIBS = -lndbm
+else
+ifeq ($(HAVE_LIBDB),yes)
+ WHICH_DB=db
+ MODULE_SIMPLE_EXTRALIBS = -ldb
+else
+ WHICH_DB=none
+endif
+endif
+
+ifeq ($(WHICH_DB),none)
+
+include ../dont_makefile
+
+else
+
+MODULE_SIMPLE_EXTRAFILES = conv
+
+include ../Simple.Rules
+
+endif
diff --git a/contrib/libpam/modules/pam_userdb/README b/contrib/libpam/modules/pam_userdb/README
new file mode 100644
index 000000000000..af78d47b1309
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/README
@@ -0,0 +1,30 @@
+pam_userdb:
+ Look up users in a .db database and verify their password against
+ what is contained in that database.
+
+RECOGNIZED ARGUMENTS:
+ debug write a message to syslog indicating success or
+ failure.
+
+ db=[path] use the [path] database for performing lookup. There
+ is no default; the module will return PAM_IGNORE if
+ no database is provided.
+
+ icase make the password verification to be case insensitive
+ (ie when working with registration numbers and such)
+
+ dump dump all the entries in the database to the log (eek,
+ don't do this by default!)
+
+MODULE SERVICES PROVIDED:
+ auth _authetication and _setcred (blank)
+
+EXAMPLE USE:
+ auth sufficient pam_userdb.so icase db=/tmp/dbtest.db
+
+AUTHOR:
+ Cristian Gafton <gafton@redhat.com>
+
+
+
+$Id: README,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $
diff --git a/contrib/libpam/modules/pam_userdb/conv.c b/contrib/libpam/modules/pam_userdb/conv.c
new file mode 100644
index 000000000000..0f13d03a4fc4
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/conv.c
@@ -0,0 +1,125 @@
+/*
+ * Conversation related functions
+ */
+
+/* $Id */
+/* Copyright at the end of the file */
+
+#define _BSD_SOURCE
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <security/pam_modules.h>
+#include <security/_pam_macros.h>
+
+#include "pam_userdb.h"
+
+/*
+ * dummy conversation function sending exactly one prompt
+ * and expecting exactly one response from the other party
+ */
+static int converse(pam_handle_t *pamh,
+ struct pam_message **message,
+ struct pam_response **response)
+{
+ int retval;
+ const struct pam_conv *conv;
+
+ retval = pam_get_item(pamh, PAM_CONV, (const void **) &conv ) ;
+ if (retval == PAM_SUCCESS)
+ retval = conv->conv(1, (const struct pam_message **)message,
+ response, conv->appdata_ptr);
+
+ return retval; /* propagate error status */
+}
+
+
+static char *_pam_delete(register char *xx)
+{
+ _pam_overwrite(xx);
+ _pam_drop(xx);
+ return NULL;
+}
+
+/*
+ * This is a conversation function to obtain the user's password
+ */
+int conversation(pam_handle_t *pamh)
+{
+ struct pam_message msg[2],*pmsg[2];
+ struct pam_response *resp;
+ int retval;
+ char * token = NULL;
+
+ pmsg[0] = &msg[0];
+ msg[0].msg_style = PAM_PROMPT_ECHO_OFF;
+ msg[0].msg = "Password: ";
+
+ /* so call the conversation expecting i responses */
+ resp = NULL;
+ retval = converse(pamh, pmsg, &resp);
+
+ if (resp != NULL) {
+ const char * item;
+ /* interpret the response */
+ if (retval == PAM_SUCCESS) { /* a good conversation */
+ token = x_strdup(resp[0].resp);
+ if (token == NULL) {
+ return PAM_AUTHTOK_RECOVER_ERR;
+ }
+ }
+
+ /* set the auth token */
+ retval = pam_set_item(pamh, PAM_AUTHTOK, token);
+ token = _pam_delete(token); /* clean it up */
+ if ( (retval != PAM_SUCCESS) ||
+ (retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&item))
+ != PAM_SUCCESS ) {
+ return retval;
+ }
+
+ _pam_drop_reply(resp, 1);
+ } else {
+ retval = (retval == PAM_SUCCESS)
+ ? PAM_AUTHTOK_RECOVER_ERR:retval ;
+ }
+
+ return retval;
+}
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/contrib/libpam/modules/pam_userdb/create.pl b/contrib/libpam/modules/pam_userdb/create.pl
new file mode 100644
index 000000000000..0e1687dfef65
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/create.pl
@@ -0,0 +1,23 @@
+#!/usr/bin/perl
+# this program creates a database in ARGV[1] from pairs given on
+# stdandard input
+#
+# $Id: create.pl,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $
+
+use DB_File;
+
+my $database = $ARGV[0];
+die "Use: check,pl <database>\n" unless ($database);
+print "Using database: $database\n";
+
+my %lusers = ();
+
+tie %lusers, 'DB_File', $database, O_RDWR|O_CREAT, 0644, $DB_HASH ;
+while (<STDIN>) {
+ my ($user, $pass) = split;
+
+ $lusers{$user} = $pass;
+}
+untie %lusers;
+
+
diff --git a/contrib/libpam/modules/pam_userdb/pam_userdb.c b/contrib/libpam/modules/pam_userdb/pam_userdb.c
new file mode 100644
index 000000000000..9da93705e514
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/pam_userdb.c
@@ -0,0 +1,304 @@
+/* pam_userdb module */
+
+/*
+ * $Id: pam_userdb.c,v 1.4 2000/12/04 15:02:16 baggins Exp $
+ * Written by Cristian Gafton <gafton@redhat.com> 1996/09/10
+ * See the end of the file for Copyright Information
+ */
+
+#include <security/_pam_aconf.h>
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <syslog.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include "pam_userdb.h"
+
+#ifdef HAVE_NDBM_H
+# include <ndbm.h>
+#else
+# ifdef HAVE_DB_H
+# define DB_DBM_HSEARCH 1 /* use the dbm interface */
+# include <db.h>
+# else
+# error "failed to find a libdb or equivalent"
+# endif
+#endif
+
+/*
+ * here, we make a definition for the externally accessible function
+ * in this file (this definition is required for static a module
+ * but strongly encouraged generally) it is used to instruct the
+ * modules include file to define the function prototypes.
+ */
+
+#define PAM_SM_AUTH
+#define PAM_SM_ACCOUNT
+
+#include <security/pam_modules.h>
+
+/* some syslogging */
+
+static void _pam_log(int err, const char *format, ...)
+{
+ va_list args;
+
+ va_start(args, format);
+ openlog(MODULE_NAME, LOG_CONS|LOG_PID, LOG_AUTH);
+ vsyslog(err, format, args);
+ va_end(args);
+ closelog();
+}
+
+char * database = NULL;
+static int ctrl = 0;
+
+static int _pam_parse(int argc, const char **argv)
+{
+ /* step through arguments */
+ for (ctrl = 0; argc-- > 0; ++argv) {
+
+ /* generic options */
+
+ if (!strcmp(*argv,"debug"))
+ ctrl |= PAM_DEBUG_ARG;
+ else if (!strcasecmp(*argv, "icase"))
+ ctrl |= PAM_ICASE_ARG;
+ else if (!strcasecmp(*argv, "dump"))
+ ctrl |= PAM_DUMP_ARG;
+ else if (!strncasecmp(*argv,"db=", 3)) {
+ database = strdup((*argv) + 3);
+ if (database == NULL)
+ _pam_log(LOG_ERR, "pam_parse: could not parse argument \"%s\"",
+ *argv);
+ } else {
+ _pam_log(LOG_ERR, "pam_parse: unknown option; %s", *argv);
+ }
+ }
+
+ return ctrl;
+}
+
+
+/*
+ * Looks up an user name in a database and checks the password
+ *
+ * return values:
+ * 1 = User not found
+ * 0 = OK
+ * -1 = Password incorrect
+ * -2 = System error
+ */
+static int user_lookup(const char *user, const char *pass)
+{
+ DBM *dbm;
+ datum key, data;
+
+ /* Open the DB file. */
+ dbm = dbm_open(database, O_RDONLY, 0644);
+ if (dbm == NULL) {
+ _pam_log(LOG_ERR, "user_lookup: could not open database `%s'",
+ database);
+ return -2;
+ }
+
+ if (ctrl &PAM_DUMP_ARG) {
+ _pam_log(LOG_INFO, "Database dump:");
+ for (key = dbm_firstkey(dbm); key.dptr != NULL;
+ key = dbm_nextkey(dbm)) {
+ data = dbm_fetch(dbm, key);
+ _pam_log(LOG_INFO, "key[len=%d] = `%s', data[len=%d] = `%s'",
+ key.dsize, key.dptr, data.dsize, data.dptr);
+ }
+ }
+ /* do some more init work */
+
+ memset(&key, 0, sizeof(key));
+ memset(&data, 0, sizeof(data));
+ key.dptr = x_strdup(user);
+ key.dsize = strlen(user);
+ user = NULL;
+
+ if (key.dptr) {
+ data = dbm_fetch(dbm, key);
+ memset(key.dptr, 0, key.dsize);
+ free(key.dptr);
+ }
+
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "password in database is [%p]`%s', len is %d",
+ data.dptr, (char *) data.dptr, data.dsize);
+ }
+
+ if (data.dptr != NULL) {
+ int compare = 0;
+ /* bingo, got it */
+ if (ctrl & PAM_ICASE_ARG)
+ compare = strncasecmp(pass, data.dptr, data.dsize);
+ else
+ compare = strncmp(pass, data.dptr, data.dsize);
+ dbm_close(dbm);
+ if (compare == 0)
+ return 0; /* match */
+ else
+ return -1; /* wrong */
+ } else {
+ if (ctrl & PAM_DEBUG_ARG) {
+ _pam_log(LOG_INFO, "error returned by dbm_fetch: %s",
+ strerror(errno));
+ }
+ dbm_close(dbm);
+ /* probably we should check dbm_error() here */
+ return 1; /* not found */
+ }
+
+ /* NOT REACHED */
+ return -2;
+}
+
+/* --- authentication management functions (only) --- */
+
+PAM_EXTERN
+int pam_sm_authenticate(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ const char *username;
+ const char *password;
+ int retval = PAM_AUTH_ERR;
+
+ /* parse arguments */
+ ctrl = _pam_parse(argc, argv);
+
+ /* Get the username */
+ retval = pam_get_user(pamh, &username, NULL);
+ if ((retval != PAM_SUCCESS) || (!username)) {
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_DEBUG,"can not get the username");
+ return PAM_SERVICE_ERR;
+ }
+
+ /* Converse just to be sure we have the password */
+ retval = conversation(pamh);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_ERR, "could not obtain password for `%s'",
+ username);
+ return -2;
+ }
+
+ /* Get the password */
+ retval = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&password);
+ if (retval != PAM_SUCCESS) {
+ _pam_log(LOG_ERR, "Could not retrive user's password");
+ return -2;
+ }
+
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_INFO, "Verify user `%s' with password `%s'",
+ username, password);
+
+ /* Now use the username to look up password in the database file */
+ retval = user_lookup(username, password);
+ switch (retval) {
+ case -2:
+ /* some sort of system error. The log was already printed */
+ return PAM_SERVICE_ERR;
+ case -1:
+ /* incorrect password */
+ _pam_log(LOG_WARNING,
+ "user `%s' denied access (incorrect password)",
+ username);
+ return PAM_AUTH_ERR;
+ case 1:
+ /* the user does not exist in the database */
+ if (ctrl & PAM_DEBUG_ARG)
+ _pam_log(LOG_NOTICE, "user `%s' not found in the database",
+ username);
+ return PAM_USER_UNKNOWN;
+ case 0:
+ /* Otherwise, the authentication looked good */
+ _pam_log(LOG_NOTICE, "user '%s' granted acces", username);
+ return PAM_SUCCESS;
+ default:
+ /* we don't know anything about this return value */
+ _pam_log(LOG_ERR,
+ "internal module error (retval = %d, user = `%s'",
+ retval, username);
+ return PAM_SERVICE_ERR;
+ }
+
+ /* should not be reached */
+ return PAM_IGNORE;
+}
+
+PAM_EXTERN
+int pam_sm_setcred(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+PAM_EXTERN
+int pam_sm_acct_mgmt(pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ return PAM_SUCCESS;
+}
+
+
+#ifdef PAM_STATIC
+
+/* static module data */
+
+struct pam_module _pam_userdb_modstruct = {
+ "pam_userdb",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+};
+
+#endif
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/contrib/libpam/modules/pam_userdb/pam_userdb.h b/contrib/libpam/modules/pam_userdb/pam_userdb.h
new file mode 100644
index 000000000000..542cdf57943f
--- /dev/null
+++ b/contrib/libpam/modules/pam_userdb/pam_userdb.h
@@ -0,0 +1,61 @@
+
+#ifndef _PAM_USERSDB_H
+#define _PAM_USERSDB_H
+/* $Id: pam_userdb.h,v 1.1.1.1 2000/06/20 22:12:09 agmorgan Exp $ */
+
+/* Header files */
+#include <security/pam_appl.h>
+
+/* argument parsing */
+#define PAM_DEBUG_ARG 0x0001
+#define PAM_ICASE_ARG 0x0002
+#define PAM_DUMP_ARG 0x0004
+
+/* Useful macros */
+#define x_strdup(s) ( (s) ? strdup(s):NULL )
+
+/* The name of the module we are compiling */
+#ifndef MODULE_NAME
+#define MODULE_NAME "pam_userdb"
+#endif /* MODULE_NAME */
+
+/* function prototypes */
+int conversation(pam_handle_t *);
+
+#endif /* _PAM_USERSDB_H */
+
+/*
+ * Copyright (c) Cristian Gafton <gafton@redhat.com>, 1999
+ * All rights reserved
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, and the entire permission notice in its entirety,
+ * including the disclaimer of warranties.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote
+ * products derived from this software without specific prior
+ * written permission.
+ *
+ * ALTERNATIVELY, this product may be distributed under the terms of
+ * the GNU Public License, in which case the provisions of the GPL are
+ * required INSTEAD OF the above restrictions. (This clause is
+ * necessary due to a potential bad interaction between the GPL and
+ * the restrictions contained in a BSD-style copyright.)
+ *
+ * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/contrib/libpam/modules/pam_warn/Makefile b/contrib/libpam/modules/pam_warn/Makefile
index 167af5a370ac..b1420538d577 100644
--- a/contrib/libpam/modules/pam_warn/Makefile
+++ b/contrib/libpam/modules/pam_warn/Makefile
@@ -1,96 +1,15 @@
#
-# $Id: Makefile,v 1.2 1997/04/05 06:20:16 morgan Exp $
+# $Id: Makefile,v 1.2 2000/11/19 23:54:06 agmorgan Exp $
#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# $Log: Makefile,v $
-# Revision 1.2 1997/04/05 06:20:16 morgan
-# fixed fakeroot
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-# Revision 1.1 1996/12/01 03:12:22 morgan
-# Initial revision
-#
-#
-# Created by Andrew Morgan <morgan@parc.power.net> 1996/11/14
-#
-
-TITLE=pam_warn
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-static/%.o : %.c
- $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-ifdef STATIC
-LIBSTATIC = lib$(TITLE).o
-endif
-
-####################### don't edit below #######################
-dummy:
+include ../../Make.Rules
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-ifdef STATIC
- $(MKDIR) ./static
-endif
-
-register:
-ifdef STATIC
- ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD)
-endif
-
-ifdef STATIC
-$(LIBOBJS): $(LIBSRC)
-
-$(LIBSTATIC): $(LIBOBJS)
- $(LD) -r -o $@ $(LIBOBJS)
-endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
+TITLE=pam_warn
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_warn/README b/contrib/libpam/modules/pam_warn/README
index f45b271c0d77..3c4bde8af20d 100644
--- a/contrib/libpam/modules/pam_warn/README
+++ b/contrib/libpam/modules/pam_warn/README
@@ -1,4 +1,4 @@
-# $Id: README,v 1.1 1996/12/01 03:12:22 morgan Exp $
+# $Id: README,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
#
This module is an authentication module that does not authenticate.
@@ -15,7 +15,10 @@ Recognized arguments:
module services provided:
- auth _autheticate and _setcred (blank)
+ auth _authenticate and _setcred (blank)
+ acct _acct_mgmt [mapped to _authenticate]
+ session _open_session and
+ _close_session [mapped to _authenticate ]
password _chauthtok [mapped to _authenticate]
diff --git a/contrib/libpam/modules/pam_warn/pam_warn.c b/contrib/libpam/modules/pam_warn/pam_warn.c
index 2a0a23d6e989..a9bcc9e70c5c 100644
--- a/contrib/libpam/modules/pam_warn/pam_warn.c
+++ b/contrib/libpam/modules/pam_warn/pam_warn.c
@@ -1,20 +1,13 @@
/* pam_warn module */
/*
- * $Id: pam_warn.c,v 1.2 1997/02/15 17:19:08 morgan Exp $
- *
- * Written by Andrew Morgan <morgan@parc.power.net> 1996/3/11
- *
- * $Log: pam_warn.c,v $
- * Revision 1.2 1997/02/15 17:19:08 morgan
- * corrected many bugs and removed fixed buffer logging
- *
- * Revision 1.1 1996/12/01 03:12:22 morgan
- * Initial revision
- *
+ * $Id: pam_warn.c,v 1.1.1.1 2000/06/20 22:12:10 agmorgan Exp $
*
+ * Written by Andrew Morgan <morgan@linux.kernel.org> 1996/3/11
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
#include <unistd.h>
#include <syslog.h>
@@ -93,18 +86,45 @@ int pam_sm_chauthtok(pam_handle_t *pamh,int flags,int argc
return pam_sm_authenticate(pamh, flags, argc, argv);
}
+PAM_EXTERN int
+pam_sm_acct_mgmt (pam_handle_t *pamh, int flags,
+ int argc, const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_open_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
+PAM_EXTERN int
+pam_sm_close_session (pam_handle_t *pamh, int flags, int argc,
+ const char **argv)
+{
+ /* map to the authentication function... */
+
+ return pam_sm_authenticate(pamh, flags, argc, argv);
+}
+
#ifdef PAM_STATIC
/* static module data */
struct pam_module _pam_warn_modstruct = {
- "pam_warn",
- pam_sm_authenticate,
- pam_sm_setcred,
- NULL,
- NULL,
- NULL,
- pam_sm_chauthtok,
+ "pam_warn",
+ pam_sm_authenticate,
+ pam_sm_setcred,
+ pam_sm_acct_mgmt,
+ pam_sm_open_session,
+ pam_sm_close_session,
+ pam_sm_chauthtok,
};
#endif
diff --git a/contrib/libpam/modules/pam_wheel/Makefile b/contrib/libpam/modules/pam_wheel/Makefile
index 553e32199668..67947f814101 100644
--- a/contrib/libpam/modules/pam_wheel/Makefile
+++ b/contrib/libpam/modules/pam_wheel/Makefile
@@ -1,94 +1,15 @@
#
+# $Id: Makefile,v 1.2 2000/11/19 23:54:06 agmorgan Exp $
+#
# This Makefile controls a build process of $(TITLE) module for
# Linux-PAM. You should not modify this Makefile (unless you know
# what you are doing!).
#
-# Created by Cristian Gafton <gafton@sorosis.ro> 1996/09/10
+# Created by Andrew Morgan <morgan@linux.kernel.org> 2000/08/27
#
-ifeq ($(HAVE_PWDBLIB),yes)
+include ../../Make.Rules
TITLE=pam_wheel
-CFLAGS += -DHAVE_PWDBLIB
-
-#
-
-LIBSRC = $(TITLE).c
-LIBOBJ = $(TITLE).o
-LIBOBJD = $(addprefix dynamic/,$(LIBOBJ))
-#LIBOBJS = $(addprefix static/,$(LIBOBJ))
-
-EXTRALS = -lpwdb
-
-dynamic/%.o : %.c
- $(CC) $(CFLAGS) $(DYNAMIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-#static/%.o : %.c
-# $(CC) $(CFLAGS) $(STATIC) $(CPPFLAGS) $(TARGET_ARCH) -c $< -o $@
-
-
-ifdef DYNAMIC
-LIBSHARED = $(TITLE).so
-endif
-
-#ifdef STATIC
-#LIBSTATIC = lib$(TITLE).o
-#endif
-
-####################### don't edit below #######################
-
-dummy:
-
- @echo "**** This is not a top-level Makefile "
- exit
-
-all: dirs $(LIBSHARED) $(LIBSTATIC) register
-
-dirs:
-ifdef DYNAMIC
- $(MKDIR) ./dynamic
-endif
-#ifdef STATIC
-# $(MKDIR) ./static
-#endif
-
-register:
-#ifdef STATIC
-# ( cd .. ; ./register_static $(TITLE) $(TITLE)/$(LIBSTATIC) )
-#endif
-
-ifdef DYNAMIC
-$(LIBOBJD): $(LIBSRC)
-
-$(LIBSHARED): $(LIBOBJD)
- $(LD_D) -o $@ $(LIBOBJD) $(EXTRALS)
-endif
-
-#ifdef STATIC
-#$(LIBOBJS): $(LIBSRC)
-#
-#$(LIBSTATIC): $(LIBOBJS)
-# $(LD) -r -o $@ $(LIBOBJS) $(EXTRALS)
-#endif
-
-install: all
- $(MKDIR) $(FAKEROOT)$(SECUREDIR)
-ifdef DYNAMIC
- $(INSTALL) -m $(SHLIBMODE) $(LIBSHARED) $(FAKEROOT)$(SECUREDIR)
-endif
-
-remove:
- rm -f $(FAKEROOT)$(SECUREDIR)/$(TITLE).so
-
-clean:
- rm -f $(LIBOBJD) $(LIBOBJS) core *~ *.so
-
-extraclean: clean
- rm -f *.a *.o *.so *.bak dynamic/* static/*
-
-.c.o:
- $(CC) $(CFLAGS) -c $<
-else
-include ../dont_makefile
-endif
+include ../Simple.Rules
diff --git a/contrib/libpam/modules/pam_wheel/pam_wheel.c b/contrib/libpam/modules/pam_wheel/pam_wheel.c
index db262d83d8c9..add72bc43f48 100644
--- a/contrib/libpam/modules/pam_wheel/pam_wheel.c
+++ b/contrib/libpam/modules/pam_wheel/pam_wheel.c
@@ -21,20 +21,16 @@
* a wheel member.
*/
+#define _BSD_SOURCE
+
#include <stdio.h>
-#define __USE_BSD
#include <unistd.h>
#include <string.h>
#include <syslog.h>
#include <stdarg.h>
#include <sys/types.h>
-#ifdef HAVE_PWDBLIB
-# include <pwdb/pwdb_public.h>
-#else
-# include <pwd.h>
-# include <grp.h>
-#endif
-
+#include <pwd.h>
+#include <grp.h>
/*
* here, we make a definition for the externally accessible function
@@ -47,9 +43,6 @@
#include <security/pam_modules.h>
-/* variables */
-static char use_group[BUFSIZ];
-
/* some syslogging */
static void _pam_log(int err, const char *format, ...)
@@ -82,7 +75,7 @@ static int is_on_list(char * const *list, const char *member)
#define PAM_TRUST_ARG 0x0004
#define PAM_DENY_ARG 0x0010
-static int _pam_parse(int argc, const char **argv)
+static int _pam_parse(int argc, const char **argv, char *use_group)
{
int ctrl=0;
@@ -122,11 +115,12 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
struct passwd *pwd, *tpwd;
struct group *grp;
int retval = PAM_AUTH_ERR;
+ char use_group[BUFSIZ];
/* Init the optional group */
- bzero(use_group,sizeof(use_group));
+ bzero(use_group,BUFSIZ);
- ctrl = _pam_parse(argc, argv);
+ ctrl = _pam_parse(argc, argv, use_group);
retval = pam_get_user(pamh,&username,NULL);
if ((retval != PAM_SUCCESS) || (!username)) {
if (ctrl & PAM_DEBUG_ARG)
@@ -171,10 +165,12 @@ int pam_sm_authenticate(pam_handle_t *pamh,int flags,int argc
}
}
- if (!use_group[0])
- grp = getgrgid(0);
- else
- grp = getgrnam(use_group);
+ if (!use_group[0]) {
+ if ((grp = getgrnam("wheel")) == NULL) {
+ grp = getgrgid(0);
+ }
+ } else
+ grp = getgrnam(use_group);
if (!grp || !grp->gr_mem) {
if (ctrl & PAM_DEBUG_ARG) {