commit 24f0b4ca2d565cdbb4fe7839ff28320706bf2386 Author: Cy Schubert Date: Wed Apr 16 19:13:41 2025 -0700 pam-krb5: Import/add pam-krb5 from eyeire.org From https://www.eyrie.org/~eagle/software/pam-krb5/: pam-krb5 provides a Kerberos PAM module that supports authentication, user ticket cache handling, simple authorization (via .k5login or checking Kerberos principals against local usernames), and password changing. It can be configured through either options in the PAM configuration itself or through entries in the system krb5.conf file, and it tries to work around PAM implementation flaws in commonly-used PAM-enabled applications such as OpenSSH and xdm. It supports both PKINIT and FAST to the extent that the underlying Kerberos libraries support these features. The reason for this import is to provide an MIT KRB5 compatible pam_krb5 PAM module. The existing pam_krb5 in FreeBS only works with Heimdal. Sponsored by: The FreeBSD Foundation diff --git a/.clang-format b/.clang-format new file mode 100644 index 000000000000..da1e4e8030d3 --- /dev/null +++ b/.clang-format @@ -0,0 +1,30 @@ +# Configuration for clang-format automated reformatting. -*- yaml -*- +# +# The canonical version of this file is maintained in the rra-c-util package, +# which can be found at . +# +# Copyright 2020-2021 Russ Allbery +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. +# +# SPDX-License-Identifier: FSFAP + +--- +Language: Cpp +BasedOnStyle: LLVM +AlignConsecutiveMacros: true +AlignEscapedNewlines: Left +AllowShortEnumsOnASingleLine: false +AlwaysBreakAfterReturnType: AllDefinitions +BreakBeforeBinaryOperators: NonAssignment +BreakBeforeBraces: WebKit +ColumnLimit: 79 +IndentPPDirectives: AfterHash +IndentWidth: 4 +IndentWrappedFunctionNames: false +MaxEmptyLinesToKeep: 2 +SpaceAfterCStyleCast: true +--- diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 000000000000..5ace4600a1f2 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml new file mode 100644 index 000000000000..6120a6cf8f58 --- /dev/null +++ b/.github/workflows/build.yaml @@ -0,0 +1,44 @@ +name: build + +on: + push: + branches-ignore: + - "debian/**" + - "pristine-tar" + - "ubuntu/**" + - "upstream/**" + tags: + - "release/*" + pull_request: + branches: + - master + +jobs: + build: + runs-on: ubuntu-latest + + env: + AUTHOR_TESTING: 1 + C_TAP_VERBOSE: 1 + + strategy: + fail-fast: false + matrix: + kerberos: + - "mit" + - "heimdal" + + steps: + - uses: actions/checkout@v2 + - name: install + run: sudo ci/install + - name: kdc-setup-mit + run: sudo ci/kdc-setup-mit + if: matrix.kerberos == 'mit' + - name: kdc-setup-heimdal + run: sudo ci/kdc-setup-heimdal + if: matrix.kerberos == 'heimdal' + - name: test + run: ci/test + env: + KERBEROS: ${{ matrix.kerberos }} diff --git a/LICENSE b/LICENSE new file mode 100644 index 000000000000..9c3abee30255 --- /dev/null +++ b/LICENSE @@ -0,0 +1,344 @@ +Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ +Comment: This file documents the copyright statements and licenses for + every file in this package in a machine-readable format. For a less + detailed, higher-level overview, see README. + . + For any copyright year range specified as YYYY-ZZZZ in this file, the + range specifies every single year in that closed interval. + +Files: * +Copyright: 1999-2000 Frank Cusack + 2005 Andres Salomon + 2005-2010, 2014-2015, 2017, 2020-2021 Russ Allbery + 2008-2014 The Board of Trustees of the Leland Stanford Junior University +License: BSD-3-clause or GPL-1+ + +Files: .clang-format docs/pam_krb5.5 docs/pam_krb5.pod pam-util/vector.c + pam-util/vector.h portable/asprintf.c portable/dummy.c + portable/issetugid.c portable/kadmin.h portable/krb5-extra.c + portable/krb5.h portable/macros.h portable/mkstemp.c portable/pam.h + portable/pam_syslog.c portable/pam_vsyslog.c portable/reallocarray.c + portable/stdbool.h portable/strndup.c portable/system.h tests/README + tests/TESTS tests/config/README tests/data/cppcheck.supp + tests/fakepam/README tests/pam-util/vector-t.c tests/portable/asprintf-t.c + tests/portable/mkstemp-t.c tests/portable/strndup-t.c +Copyright: 2005-2012, 2014-2021 Russ Allbery + 2006-2014 The Board of Trustees of the Leland Stanford Junior University +License: all-permissive + Copying and distribution of this file, with or without modification, are + permitted in any medium without royalty provided the copyright notice and + this notice are preserved. This file is offered as-is, without any + warranty. + +Files: Makefile.in +Copyright: 1994-2021 Free Software Foundation, Inc. + 1999-2000 Frank Cusack + 2005 Andres Salomon + 2005-2007, 2014, 2017, 2020-2021 Russ Allbery + 2009, 2011-2012 + The Board of Trustees of the Leland Stanford Junior University +License: FSF-unlimited, and BSD-3-clause or GPL-1+ + +Files: aclocal.m4 m4/ltoptions.m4 m4/ltsugar.m4 m4/ltversion.m4 + m4/lt~obsolete.m4 +Copyright: 1996-2021 Free Software Foundation, Inc. +License: FSF-unlimited + +Files: build-aux/ar-lib build-aux/compile build-aux/depcomp + build-aux/missing +Copyright: 1996-2021 Free Software Foundation, Inc. +License: GPL-2+ with Autoconf exception or BSD-3-clause or GPL-1+ + +Files: build-aux/config.guess build-aux/config.sub +Copyright: 1992-2018 Free Software Foundation, Inc. +License: GPL-3+ with Autoconf exception or BSD-3-clause or GPL-1+ + +Files: build-aux/install-sh +Copyright: 1994 X Consortium +License: X11 + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR + OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + OTHER DEALINGS IN THE SOFTWARE. + . + Except as contained in this notice, the name of the X Consortium shall + not be used in advertising or otherwise to promote the sale, use or other + dealings in this Software without prior written authorization from the X + Consortium. + +Files: build-aux/ltmain.sh +Copyright: 1996-2015 Free Software Foundation, Inc. +License: GPL-2+ with Libtool exception or BSD-3-clause or GPL-1+, and GPL-3+ with Libtool exception or BSD-3-clause or GPL-1+, and GPL-3+ + +Files: ci/install ci/kdc-setup-heimdal ci/kdc-setup-mit ci/test + pam-util/args.c pam-util/args.h pam-util/logging.c pam-util/logging.h + pam-util/options.c pam-util/options.h tests/data/generate-krb5-conf + tests/data/valgrind.supp tests/docs/pod-spelling-t tests/docs/pod-t + tests/docs/spdx-license-t tests/fakepam/config.c tests/fakepam/data.c + tests/fakepam/general.c tests/fakepam/internal.h tests/fakepam/kuserok.c + tests/fakepam/logging.c tests/fakepam/pam.h tests/fakepam/script.c + tests/fakepam/script.h tests/pam-util/args-t.c tests/pam-util/fakepam-t.c + tests/pam-util/logging-t.c tests/pam-util/options-t.c tests/runtests.c + tests/style/obsolete-strings-t tests/tap/basic.c tests/tap/basic.h + tests/tap/kadmin.c tests/tap/kadmin.h tests/tap/kerberos.c + tests/tap/kerberos.h tests/tap/libtap.sh tests/tap/macros.h + tests/tap/perl/Test/RRA.pm tests/tap/perl/Test/RRA/Automake.pm + tests/tap/perl/Test/RRA/Config.pm tests/tap/process.c tests/tap/process.h + tests/tap/string.c tests/tap/string.h tests/valgrind/logs-t +Copyright: 2000-2002, 2004-2021 Russ Allbery + 2001-2002, 2004-2014 + The Board of Trustees of the Leland Stanford Junior University +License: Expat + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the + "Software"), to deal in the Software without restriction, including + without limitation the rights to use, copy, modify, merge, publish, + distribute, sublicense, and/or sell copies of the Software, and to permit + persons to whom the Software is furnished to do so, subject to the + following conditions: + . + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + . + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY + CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT + OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Files: configure +Copyright: 1992-1996, 1998-2017, 2020-2021 Free Software Foundation, Inc. +License: FSF-configure, and GPL-2+ with Libtool exception or BSD-3-clause or GPL-1+ + +Files: m4/cc-flags.m4 +Copyright: 2006, 2009, 2016 Internet Systems Consortium, Inc. + 2016-2021 Russ Allbery +License: ISC + Permission to use, copy, modify, and distribute this software for any + purpose with or without fee is hereby granted, provided that the above + copyright notice and this permission notice appear in all copies. + . + THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH + REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY + SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +Files: m4/clang.m4 m4/kadm5clnt.m4 m4/krb5-config.m4 m4/krb5-pkinit.m4 + m4/krb5.m4 m4/ld-version.m4 m4/lib-depends.m4 m4/lib-helper.m4 + m4/lib-pathname.m4 m4/pam-const.m4 +Copyright: 2005-2014 + The Board of Trustees of the Leland Stanford Junior University + 2007, 2015, 2018, 2020-2021 Russ Allbery + 2007-2008 Markus Moeller + 2008-2010 Free Software Foundation, Inc. +License: unlimited + This file is free software; the authors give unlimited permission to copy + and/or distribute it, with or without modifications, as long as this + notice is preserved. + +Files: m4/libtool.m4 +Copyright: 1996-2001, 2003-2015 Free Software Foundation, Inc. +License: FSF-unlimited, and GPL-2+ with Libtool exception or BSD-3-clause or GPL-1+ + +Files: portable/krb5-profile.c +Copyright: 1985-2005 the Massachusetts Institute of Technology +License: MIT-Kerberos + Export of this software from the United States of America may require + a specific license from the United States Government. It is the + responsibility of any person or organization contemplating export to + obtain such a license before exporting. + . + WITHIN THAT CONSTRAINT, permission to use, copy, modify, and + distribute this software and its documentation for any purpose and + without fee is hereby granted, provided that the above copyright + notice appear in all copies and that both that copyright notice and + this permission notice appear in supporting documentation, and that + the name of M.I.T. not be used in advertising or publicity pertaining + to distribution of the software without specific, written prior + permission. Furthermore if you modify this software you must label + your software as modified software and not distribute it in such a + fashion that it might be confused with the original MIT software. + M.I.T. makes no representations about the suitability of this software + for any purpose. It is provided "as is" without express or implied + warranty. + . + THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + . + Individual source code files are copyright MIT, Cygnus Support, + OpenVision, Oracle, Sun Soft, FundsXpress, and others. + . + Project Athena, Athena, Athena MUSE, Discuss, Hesiod, Kerberos, Moira, + and Zephyr are trademarks of the Massachusetts Institute of Technology + (MIT). No commercial use of these trademarks may be made without + prior written permission of MIT. + . + "Commercial use" means use of a name in a product or other for-profit + manner. It does NOT prevent a commercial firm from referring to the + MIT trademarks in order to convey information (although in doing so, + recognition of their trademark status should be given). + +License: BSD-3-clause or GPL-1+ + 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 General 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. + +License: FSF-configure + This script is free software; the Free Software Foundation gives unlimited + permission to copy, distribute and modify it. + +License: FSF-unlimited + This file is free software; the Free Software Foundation gives unlimited + permission to copy and/or distribute it, with or without modifications, as + long as this notice is preserved. + . + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +License: GPL-2+ with Autoconf exception + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + . + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + . + You should have received a copy of the GNU General Public License along + with this program. If not, see . + . + As a special exception to the GNU General Public License, if you + distribute this file as part of a program that contains a configuration + script generated by Autoconf, you may include it under the same + distribution terms that you use for the rest of that program. +Comment: The option described in the license has been accepted and these + files are distributed under the same terms as the package as a whole, as + described at the top of this file. + +License: GPL-2+ with Libtool exception + This file is part of GNU Libtool. + . + GNU Libtool is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + . + As a special exception to the GNU General Public License, if you + distribute this file as part of a program or library that is built using + GNU Libtool, you may include this file under the same distribution terms + that you use for the rest of that program. + . + GNU Libtool is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. +Comment: The option described in the license has been accepted and these + files are distributed under the same terms as the package as a whole, as + described at the top of this file. + +License: GPL-3+ + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + . + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + +License: GPL-3+ with Autoconf exception + This file is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the + Free Software Foundation; either version 3 of the License, or (at your + option) any later version. + . + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General + Public License for more details. + . + You should have received a copy of the GNU General Public License along + with this program; if not, see . + . + As a special exception to the GNU General Public License, if you + distribute this file as part of a program that contains a configuration + script generated by Autoconf, you may include it under the same + distribution terms that you use for the rest of that program. This + Exception is an additional permission under section 7 of the GNU General + Public License, version 3 ("GPLv3"). +Comment: The option described in the license has been accepted and these + files are distributed under the same terms as the package as a whole, as + described at the top of this file. + +License: GPL-3+ with Libtool exception + GNU Libtool is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + . + As a special exception to the GNU General Public License, if you + distribute this file as part of a program or library that is built + using GNU Libtool, you may include this file under the same + distribution terms that you use for the rest of that program. + . + GNU Libtool is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. +Comment: The option described in the license has been accepted and these + files are distributed under the same terms as the package as a whole, as + described at the top of this file. + diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 000000000000..ef28c36ad045 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,210 @@ +# Automake makefile for pam-krb5. +# +# Written by Russ Allbery +# Copyright 2005-2007, 2014, 2017, 2020-2021 Russ Allbery +# Copyright 2009, 2011-2012 +# The Board of Trustees of the Leland Stanford Junior University +# Copyright 2005 Andres Salomon +# Copyright 1999-2000 Frank Cusack +# +# SPDX-License-Identifier: BSD-3-clause or GPL-1+ + +ACLOCAL_AMFLAGS = -I m4 +EXTRA_DIST = .clang-format .gitignore .github LICENSE README.md bootstrap \ + ci/README.md ci/files/heimdal/heimdal-kdc \ + ci/files/heimdal/kadmind.acl ci/files/heimdal/kdc.conf \ + ci/files/heimdal/krb5.conf ci/files/heimdal/pki-mapping \ + ci/files/mit/extensions.client ci/files/mit/extensions.kdc \ + ci/files/mit/kadm5.acl ci/files/mit/kdc.conf ci/files/mit/krb5.conf \ + ci/kdc-setup-heimdal ci/kdc-setup-mit ci/install ci/test \ + docs/docknot.yaml docs/pam_krb5.pod module/pam_krb5.map \ + module/pam_krb5.sym tests/README tests/TESTS tests/config/README \ + tests/data/cppcheck.supp tests/data/generate-krb5-conf \ + tests/data/krb5-pam.conf tests/data/krb5.conf tests/data/perl.conf \ + tests/data/scripts tests/data/valgrind.supp \ + tests/docs/pod-spelling-t tests/docs/pod-t \ + tests/docs/spdx-license-t tests/fakepam/README tests/tap/libtap.sh \ + tests/tap/perl/Test/RRA.pm tests/tap/perl/Test/RRA/Automake.pm \ + tests/tap/perl/Test/RRA/Config.pm tests/style/obsolete-strings-t \ + tests/valgrind/logs-t + +# Everything we build needs the Kerbeors headers and library flags. +AM_CPPFLAGS = $(KRB5_CPPFLAGS) +AM_LDFLAGS = $(KRB5_LDFLAGS) + +noinst_LTLIBRARIES = pam-util/libpamutil.la portable/libportable.la +portable_libportable_la_SOURCES = portable/dummy.c portable/kadmin.h \ + portable/krb5.h portable/macros.h portable/pam.h portable/stdbool.h \ + portable/system.h +portable_libportable_la_LIBADD = $(LTLIBOBJS) +pam_util_libpamutil_la_SOURCES = pam-util/args.c pam-util/args.h \ + pam-util/logging.c pam-util/logging.h pam-util/options.c \ + pam-util/options.h pam-util/vector.c pam-util/vector.h + +if HAVE_LD_VERSION_SCRIPT + VERSION_LDFLAGS = -Wl,--version-script=${srcdir}/module/pam_krb5.map +else + VERSION_LDFLAGS = -export-symbols ${srcdir}/module/pam_krb5.sym +endif + +pamdir = $(libdir)/security +pam_LTLIBRARIES = module/pam_krb5.la +module_pam_krb5_la_SOURCES = module/account.c module/alt-auth.c \ + module/auth.c module/cache.c module/context.c module/fast.c \ + module/internal.h module/options.c module/password.c \ + module/prompting.c module/public.c module/setcred.c \ + module/support.c +module_pam_krb5_la_LDFLAGS = -module -shared \ + -avoid-version $(VERSION_LDFLAGS) $(AM_LDFLAGS) +module_pam_krb5_la_LIBADD = pam-util/libpamutil.la portable/libportable.la \ + $(KRB5_LIBS) +dist_man_MANS = docs/pam_krb5.5 + +# The manual page is normally generated by the bootstrap script, but add a +# Makefile rule to regenerate it if it is modified. +docs/pam_krb5.5: $(srcdir)/docs/pam_krb5.pod + pod2man --release="$(VERSION)" --center=pam-krb5 -s 5 \ + $(srcdir)/docs/pam_krb5.pod > $@ + +# Work around the GNU Coding Standards, which leave all the Autoconf and +# Automake stuff around after make maintainer-clean, thus making that command +# mostly worthless. +DISTCLEANFILES = config.h.in~ configure~ +MAINTAINERCLEANFILES = Makefile.in aclocal.m4 build-aux/compile \ + build-aux/config.guess build-aux/config.sub build-aux/depcomp \ + build-aux/install-sh build-aux/ltmain.sh build-aux/missing \ + config.h.in configure docs/pam_krb5.5 m4/libtool.m4 m4/ltoptions.m4 \ + m4/ltsugar.m4 m4/ltversion.m4 m4/lt~obsolete.m4 + +# Separate target for a human to request building everything with as many +# compiler warnings enabled as possible. +warnings: + $(MAKE) V=0 AM_CFLAGS='$(WARNINGS_CFLAGS) $(AM_CFLAGS)' \ + KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_WARNINGS)' + $(MAKE) V=0 AM_CFLAGS='$(WARNINGS_CFLAGS) $(AM_CFLAGS)' \ + KRB5_CPPFLAGS='$(KRB5_CPPFLAGS_WARNINGS)' $(check_PROGRAMS) + +# The bits below are for the test suite, not for the main package. +check_PROGRAMS = tests/runtests tests/module/alt-auth-t \ + tests/module/bad-authtok-t tests/module/basic-t \ + tests/module/cache-cleanup-t tests/module/cache-t \ + tests/module/expired-t tests/module/fast-anon-t tests/module/fast-t \ + tests/module/long-t tests/module/no-cache-t tests/module/pam-user-t \ + tests/module/password-t tests/module/pkinit-t tests/module/realm-t \ + tests/module/stacked-t tests/module/trace-t tests/pam-util/args-t \ + tests/pam-util/fakepam-t tests/pam-util/logging-t \ + tests/pam-util/options-t tests/pam-util/vector-t \ + tests/portable/asprintf-t tests/portable/mkstemp-t \ + tests/portable/strndup-t +tests_runtests_CPPFLAGS = -DC_TAP_SOURCE='"$(abs_top_srcdir)/tests"' \ + -DC_TAP_BUILD='"$(abs_top_builddir)/tests"' +check_LIBRARIES = tests/fakepam/libfakepam.a tests/tap/libtap.a +tests_fakepam_libfakepam_a_SOURCES = tests/fakepam/config.c \ + tests/fakepam/data.c tests/fakepam/general.c \ + tests/fakepam/internal.h tests/fakepam/kuserok.c \ + tests/fakepam/logging.c tests/fakepam/pam.h tests/fakepam/script.c \ + tests/fakepam/script.h +tests_tap_libtap_a_CPPFLAGS = $(KADM5CLNT_CPPFLAGS) $(AM_CPPFLAGS) +tests_tap_libtap_a_SOURCES = tests/tap/basic.c tests/tap/basic.h \ + tests/tap/kadmin.c tests/tap/kadmin.h tests/tap/kerberos.c \ + tests/tap/kerberos.h tests/tap/macros.h tests/tap/process.c \ + tests/tap/process.h tests/tap/string.c tests/tap/string.h + +# The list of objects and libraries used for module testing by programs that +# link with the fake PAM library or with both it and the module. +MODULE_OBJECTS = module/account.lo module/alt-auth.lo module/auth.lo \ + module/cache.lo module/context.lo module/fast.lo module/options.lo \ + module/password.lo module/prompting.lo module/public.lo \ + module/setcred.lo module/support.lo pam-util/libpamutil.la \ + tests/fakepam/libfakepam.a + +# The test programs themselves. +tests_module_alt_auth_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_bad_authtok_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_basic_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_cache_cleanup_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_cache_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_expired_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KADM5CLNT_LDFLAGS) $(KADM5CLNT_LIBS) \ + $(KRB5_LIBS) +tests_module_fast_anon_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_fast_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_long_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_no_cache_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_pam_user_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_password_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_pkinit_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_realm_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_stacked_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_module_trace_t_LDADD = $(MODULE_OBJECTS) tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_pam_util_args_t_LDADD = pam-util/libpamutil.la \ + tests/fakepam/libfakepam.a tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_pam_util_fakepam_t_LDADD = tests/fakepam/libfakepam.a \ + tests/tap/libtap.a portable/libportable.la +tests_pam_util_logging_t_LDADD = pam-util/libpamutil.la \ + tests/fakepam/libfakepam.a tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_pam_util_options_t_LDADD = pam-util/libpamutil.la \ + tests/fakepam/libfakepam.a tests/tap/libtap.a \ + portable/libportable.la $(KRB5_LIBS) +tests_pam_util_vector_t_LDADD = pam-util/libpamutil.la \ + tests/fakepam/libfakepam.a tests/tap/libtap.a \ + portable/libportable.la +tests_portable_asprintf_t_SOURCES = tests/portable/asprintf-t.c \ + tests/portable/asprintf.c +tests_portable_asprintf_t_LDADD = tests/tap/libtap.a portable/libportable.la +tests_portable_mkstemp_t_SOURCES = tests/portable/mkstemp-t.c \ + tests/portable/mkstemp.c +tests_portable_mkstemp_t_LDADD = tests/tap/libtap.a portable/libportable.la +tests_portable_strndup_t_SOURCES = tests/portable/strndup-t.c \ + tests/portable/strndup.c +tests_portable_strndup_t_LDADD = tests/tap/libtap.a portable/libportable.la + +check-local: $(check_PROGRAMS) + cd tests && ./runtests -l '$(abs_top_srcdir)/tests/TESTS' + +# Used by maintainers to check the source code with cppcheck. +check-cppcheck: + cd $(abs_top_srcdir) && \ + find . -name .git -prune -o -name '*.[ch]' -print \ + | cppcheck -q --force --error-exitcode=2 --file-list=- \ + --suppressions-list=tests/data/cppcheck.supp \ + --enable=warning,performance,portability,style + +# The full path to valgrind and its options, used when doing valgrind +# testing. +VALGRIND_COMMAND = $(PATH_VALGRIND) --leak-check=full \ + --trace-children=yes \ + --trace-children-skip=/bin/sh,*/generate-krb5-conf \ + --suppressions=$(abs_top_srcdir)/tests/data/valgrind.supp \ + --log-file=$(abs_top_builddir)/tests/tmp/valgrind/log.%p + +# Used by maintainers to run the main test suite under valgrind. +check-valgrind: $(check_PROGRAMS) + rm -rf $(abs_top_builddir)/tests/tmp + mkdir $(abs_top_builddir)/tests/tmp + mkdir $(abs_top_builddir)/tests/tmp/valgrind + C_TAP_VALGRIND="$(VALGRIND_COMMAND)" tests/runtests \ + -l '$(abs_top_srcdir)/tests/TESTS' + +# Used by maintainers to reformat all source code using clang-format and +# excluding some files. +reformat: + find . -name '*.[ch]' \! -name krb5-profile.c -print \ + | xargs clang-format -style=file -i diff --git a/NEWS b/NEWS new file mode 100644 index 000000000000..b5c007ef9359 --- /dev/null +++ b/NEWS @@ -0,0 +1,1215 @@ + User-Visible pam-krb5 Changes + +pam-krb5 4.11 (2021-10-17) + + Properly support calling pam_end with PAM_DATA_SILENT by not deleting + the underlying ticket cache. This flag is used when the application + is closing the PAM session after a fork to free memory resources, but + doesn't intend to free resources external to the process because + another process may still depend on them. Thanks to Andrew G. Morgan + for the report. (GitHub #21) + + Stop attempting to guess the correct PAM module installation path on + Linux systems when --prefix is set to /usr and instead document that + --libdir will probably need to be set explicitly. The previous logic + is now broken on Debian usrmerge systems and the guesswork seems too + fragile to maintain. + + Update to rra-c-util 10.0: + + * Support Autoconf 2.71 without warnings. + * Tests written in Perl now require Perl 5.10 or later. + +pam-krb5 4.10 (2021-03-20) + + When re-retrieving the authenticated principal from the current cache, + ensure the stored principal in the authentication context is always + either valid or NULL. Otherwise, a failure of krb5_cc_get_principal + could result in a double free. Thanks to Michael Muehle for the + report. + + Update to rra-c-util 9.0: + + * Check that at least one Kerberos header file was found and works. + * Use AS_ECHO in all Autoconf macros in preference to echo. + * Fix portability of reallocarray on NetBSD systems. + * Stop providing a replacement for a broken snprintf. + + Update to C TAP Harness 4.7: + + * Fix warnings with GCC 10. + +pam-krb5 4.9 (2020-03-30) + + SECURITY: All previous versions of this module could overflow the + buffer provided by the underlying Kerberos library for the response to + a prompt by writing a single nul character past the end of the buffer. + (CVE-2020-10595) + + Support use_pkinit with MIT Kerberos. (Debian Bug#871699) + + Reject passwords as long or longer than PAM_MAX_RESP_SIZE (normally + 512 octets), since extremely long passwords can be used for a denial + of service attack via the Kerberos string to key function. Thanks to + Florian Best for pointing out this issue and suggesting a good fix. + + Use explicit_bzero instead of memset, where available, to overwrite + the memory used by PAM responses before freeing. This reduces the + lifetime of passwords and other secrets in memory. + + Return more accurate errors from the Kerberos prompter function if it + was unable to prompt for the password. This may translate into better + debug log messages and, in some situations, returning the slightly + more accurate PAM_AUTHINFO_UNAVAIL instead of PAM_AUTH_ERR. + + Fix an edge-case memory leak in pam_chauthtok when prompting for a new + password for an ignored user. + + Ensure the module/basic test will run properly when the system + krb5.conf file does not specify a default realm. Reported by TBK. + + Update to rra-c-util 8.2: + + * Fix support for configuring the test suite with a krb5.conf file. + * Drop support for Perl 5.6. + * Reformat all C source using clang-format 10. + * Remove bogus snprintf tests. + * Fix misplaced va_end in the pam-util putil_log_failure function. + * Skip checking for krb5-config on the path if a prefix was given. + * Add SPDX-License-Identifier headers to all substantial source files. + + Update to C TAP Harness 4.6: + + * Fixed malloc error checking in bstrndup. + * Fix (harmless) allocation error in runtests driver. + * Add support for valgrind testing via test list options. + * Report test failures as left and right, not wanted and seen. + * Fix is_string comparisons involving NULL pointers and "(null)". + * Add SPDX-License-Identifier headers to all substantial source files. + +pam-krb5 4.8 (2017-12-30) + + When verifying that an expired password can still be used to get + kadmin/changepw credentials, correctly set the credential options for + getting password change credentials, not for getting initial + credentials. This should fix password change issues when, for + example, krb5.conf requests that all tickets be proxiable but + kadmin/changepw doesn't allow proxiable credentials. Thanks to + Florian Best for the bug report. + + When built against recent versions of Heimdal with richer status codes + from PKINIT attempts, report to the user the reason for a PKINIT + failure. Based on work by Henry Jacques. + + Document the test suite configuration files required to run the PKINIT + tests. + + Fix expired password tests to work with Heimdal 7.0.1 and later. + + Better document that the default Kerberos library ticket cache + location is not used (and why), and how to set configuration + parameters in krb5.conf. Thanks, Matthew Gabeler-Lee. (Debian + Bug#872943) + + Compile cleanly under GCC 7 and Clang warnings and Clang's static + analyzer. + + Rename the script to bootstrap from a Git checkout to bootstrap, + matching the emerging consensus in the Autoconf world. + + Update to rra-c-util 7.0: + + * Fix new warnings in GCC 7. + * Support a warning build under Clang. + * Avoid zero-length allocations in reallocarray and vector. + * Probe for warning flags instead of hard-coding a list. + * New test for obsolete URLs and email addresses. + * Remove unused portable replacements for strlcpy and strlcat. + * Use C_TAP_SOURCE and C_TAP_BUILD environment variables in tests. + * Fix portability defines for anonymous principal strings. + * Clear errno on pam_modutil_getpwnam to improve other testing. + * Add portability defines for macOS's PAM implementation. + * Add new Autoconf macro to probe for pam_strerror const usage. + * Support Solaris 10's included Kerberos. + + Update to C TAP Harness 4.2: + + * Avoid zero-length allocations in breallocarray. + * Add is_blob and is_bool functions. + * Use C_TAP_SOURCE and C_TAP_BUILD environment variables in tests. + * Fix segfault in runtests with an empty test list. + * Display verbose test results with -v or C_TAP_VERBOSE. + * Test infrastructure builds cleanly with Clang warnings. + +pam-krb5 4.7 (2014-12-25) + + Add a no_update_user option that disables the normal update of the + PAM_USER PAM variable after canonicalization of the username. When + this is set, pam-krb5 will not convert full principal names to local + usernames where possible for the rest of the PAM stack. + + Suppress spurious password prompt from Heimdal when authenticating + with PKINIT. + + Map unknown realm errors from the Kerberos libraries to the PAM error + code PAM_AUTHINFO_UNAVAIL instead of PAM_AUTH_ERR. + + Treat an KRB5_GET_IN_TKT_LOOP error as an incorrect password. Heimdal + KDCs sometimes return it, and Heimdal kinit treats it this way. + Similarly, treat a KRB5_BAD_ENCTYPE error as an incorrect password, + since this error is returned by a Heimdal 1.6-rc2 KDC for incorrect + preauth from a MIT Kerberos 1.12.1 client. + + Add the version number at which each module option was added with its + current meaning to the documentatation. + + Update to rra-c-util 5.6: + + * Suppress warnings from Kerberos headers in non-system paths. + * Fix probing for Heimdal's libroken to work with older versions. + * Fix Kerberos header detection if root or include paths are given. + * Pass --deps to krb5-config in the non-reduced-dependencies case. + * Provide a reallocarray replacement for platforms without it. + * Use reallocarray where appropriate. + * Drop checks for NULL before freeing pointers. + * Drop explicit pointer initialization to NULL and rely on calloc. + * Check the return status of snprintf and vsnprintf properly. + * Preserve errno if snprintf fails in vasprintf replacement. + * Suppress a dummy symbol in the client library that could leak. + * Fix syntax errors when building with a C++ compiler. + * Avoid test suite failures where tested functions are macros. + + Update to C TAP Harness 3.2: + + * Reopen standard input to /dev/null when running a test list. + * Don't leak extraneous file descriptors to tests. + * Suppress lazy plans and test summaries if the test failed with bail. + * bail and sysbail now exit with status 255 to match Test::More. + * runtests now treats the command line as a list of tests by default. + * The full test executable path can now be passed to runtests -o. + * Improved harness output for tests with lazy plans. + * Improved harness output to a terminal for some abort cases. + * Flush harness output after each test even when not on a terminal. + +pam-krb5 4.6 (2012-06-02) + + Add an anon_fast option that attempts anonymous authentication + (generally implemented via anonymous PKINIT inside the Kerberos + library) and then, if successful, uses those credentials for FAST + armor. If fast_ccache and anon_fast are both specified, anonymous + authentication will be used as a fallback if the specified FAST ticket + cache doesn't exist. Based on patches from Yair Yarom. + + Add a user_realm option to only set the realm for unqualified user + principals. This differs from the existing realm option in that realm + also changes the default realm for authorization decisions and for + verification of credentials. Update the realm option documentation to + clarify the differences and remove incorrect information. Patch from + Roland C. Dowdeswell. + + Add a no_prompt option to suppress the PAM module's prompt for the + user's password and defer all prompting to the Kerberos library. This + allows the Kerberos library to have complete control of the prompting + process, which may be desirable if authentication mechanisms other + than password are in use. Be aware that, with this option set, the + PAM module has no control over the contents of the prompt and cannot + store the user's password in the PAM data. Based on a patch by Yair + Yarom. + + Add a silent option to force the module to behave as if the + application had passed in PAM_SILENT and suppress text messages and + errors from the Kerberos library. Patch from Yair Yarom. + + Add preliminary support for Kerberos trace logging via a trace option + that enables trace logging if supported by the underlying Kerberos + library. The option takes as an argument the file name to which to + log trace output. This option does not yet work with any released + version of Kerberos, but may work with the next release of MIT + Kerberos. + + MIT Kerberos does not add a colon and space to its password prompts, + but Heimdal does. pam-krb5 previously unconditionally added a colon + and space, resulting in doubled colons with Heimdal. Work around this + inconsistency by not adding the colon and space if already present. + + Fix alt_auth_map support to preserve the realm of the authentication + identity when forming the alternate authentication principal, matching + the documentation. + + Document that the alt_auth_map format may contain a realm to force all + mapped principals to be in that realm. In that case, don't add the + realm of the authentication identity. Note that this can be used as a + simple way to attempt authentication in an alternate realm first and + then fall back to the local realm, although any complex attempt at + authentication in multiple realms should instead run the module + multiple times with different realm settings. + + Avoid a NULL pointer dereference if krb5_init_context fails. + + Fix initialization of time values in the module configuration on + platforms (like S/390X) where krb5_deltat is not equivalent to long. + + Close a memory leak when search_k5login is set but the user has no + .k5login file. + + Close several memory leaks in alt_auth_map support. + + Suppress bogus error messages about unknown option for the realm + option. The option was being parsed and honored despite the error. + + Retry authentication under try_first_pass on several other errors in + addition to decrypt integrity check errors to handle a wider array of + possible "password incorrect" error messages from the KDC. + + Update to rra-c-util 4.4: + + * Replacement strndup now works with non-nul-terminated strings. + * New Kerberos test setup that simplifies writing tests. + * Add -D_FORTIFY_SOURCE=2 to the make warnings flags. + * Use --deps flag to krb5-config by default. + * Suppress __alloc_size__ attribute with older versions of gcc. + * Suppress attribute warnings for non-gcc compilers. + + Update to C TAP Harness 1.12: + + * Add bstrndup to the basic C TAP library. + * Only use feature-test macros when requested or built with gcc -ansi. + * New tests/tap/macros.h header with some common definitions. + * Drop is_double from the C TAP library to avoid requiring -lm. + * Avoid using local in the shell libtap.sh library. + +pam-krb5 4.5 (2011-12-24) + + Suppress the notice that the password is being changed because it's + expired if force_first_pass or use_first_pass is set in the password + stack, indicating that it's stacked with another module that's also + doing password changes. This is arguable, but without this change the + notification message of why the password is being changed shows up + confusingly in the middle of the password change interaction. Based + on a patch by William Yang. + + Some old versions of Heimdal (0.7.2 in OpenBSD 4.9, specifically) + reportedly return KRB5KDC_ERR_KEY_EXP for accounts with expired + keys even if the supplied password is wrong. Work around this by + confirming that the PAM module can obtain tickets for kadmin/changepw + before returning a password expiration error instead of an invalid + password error. Based on a patch by William Yang. + + The location of the temporary root-owned ticket cache created during + the authentication process is now also controlled by the ccache_dir + option (but not the ccache option) rather than forced to be in /tmp. + This will allow system administrators to configure an alternative + cache directory so that pam-krb5 can continue working when /tmp is + full. + + Report more specific errors in syslog if authorization checks (such as + .k5login checks) fail. + + Pass a NULL principal to krb5_set_password with MIT client libraries + to prefer the older change password protocol for compatibility with + older KDCs. This is not necessary on Heimdal since Heimdal's + krb5_set_password tries both protocols. + + Improve logging and authorization checks when defer_pwchange is set + and a user authenticates with an expired password. + + When probing for Kerberos libraries, always add any supplemental + libraries found to that point to the link command. This will fix + configure failures on platforms without working transitive shared + library dependencies. + + Close some memory leaks where unparsed Kerberos principal names were + never freed. + + Restructure the code to work with OpenPAM's default PAM build + machinery, which exports a struct containing module entry points + rather than public pam_sm_* functions. Thanks to Fredrik Pettai for + the information. + + In debug logging, report symbolic names for PAM flags on PAM function + entry rather than the numeric PAM flags. This helps with automated + testing and with debugging PAM problems on different operating + systems. + + Include if is missing, which permits finding + the header file on NetBSD systems. Thanks to Fredrik Pettai for the + report. + + Replace the Kerberos compatibility layer with equivalent but + better-structured code from rra-c-util 4.0. + + Avoid krb5-config and use manual library probing if --with-krb5-lib or + --with-krb5-include were given to configure. This avoids having to + point configure at a nonexistent krb5-config to override its results. + + Use PATH_KRB5_CONFIG instead of KRB5_CONFIG to locate krb5-config in + configure, to avoid a conflict with the variable used by the Kerberos + libraries to find krb5.conf. + + Change references to Kerberos v5 to just Kerberos in the + documentation. Kerberos v5 has been the default version of Kerberos + for over ten years now. + + Update to rra-c-util 4.0: + + * Add notices to all files copied over from rra-c-util. + * Include strings.h for additional POSIX functions where found. + * Fix detection of whether PAM uses const on FreeBSD. + * Update warning flags for make warnings for GCC 4.6.1. + * Limit symbol exports even on systems without GNU ld. + * Fix replacement mkstemp to use long long where available. + * Improve stripping of /usr/include from krb5-config results. + * Use issetugid where available, not the misnamed issetuidgid. + + Update to C TAP Harness 1.9: + + * Add bmalloc, bcalloc, brealloc, and bstrdup TAP library functions. + * Fix runtests to honor -s even if BUILD and -b aren't given. + * Add test_tmpdir and test_tmpdir_free to TAP library. + * runtests now frees all allocated resources on exit. + +pam-krb5 4.4 (2010-12-31) + + Do not prompt for a password when try_pkinit is set and the module is + built against MIT Kerberos. This fixes a spurious password prompt + introduced in 4.1, but partly reintroduces the bug fixed in 4.1 where + the user's password is not saved in the PAM data if the authentication + falls back to password when PKINIT fails. This requires more work + to fix and will be addressed in a subsequent release. Thanks to + Бранко Мајић (Branko Majic) for the report. + + Reorganize the configuration section of the pam_krb5 man page to + divide the many PAM module options into sections. + + When probing for (part of AIX's bundled Kerberos + implementation), include before attempting to include that + header to quiet confusing Autoconf warnings. Reported by Wilfried + Weiss. + + Update to rra-c-util 3.0: + + * Fix compilation of the replacement snprintf for old systems. + * Look for krb5-config in /usr/kerberos/bin for Red Hat systems. + * Fix compilation with OpenBSD's Heimdal without separate libroken. + +pam-krb5 4.3 (2010-06-09) + + Add a fast_ccache option that, if set, points to a Kerberos ticket + cache used for Flexible Authentication Secure Tunneling (FAST) to + protect the authentication. FAST is a mechanism to protect Kerberos + against password guessing attacks and provide other security + improvements. This option is only available when built against + Kerberos libraries with FAST support (currently only MIT Kerberos 1.7 + or later). Patch from Sam Hartman. + + Fix error in freeing a previous alt_auth_map setting when parsing + configuration options. Patch from Sam Hartman. + + Fix the linker flags for Solaris with the native compiler. Thanks, + Kevin Sumner. + +pam-krb5 4.2 (2009-11-25) + + Add a new fail_pwchange option, which suppresses password changes for + expired passwords and treats expired passwords the same as incorrect + passwords. + + Include all the new header files from the portability code so that + it will actually compile on non-Linux platforms. + +pam-krb5 4.1 (2009-11-20) + + Return PAM_SUCCESS, not PAM_USER_UNKNOWN, for ignored users in + pam_setcred. It's safe to return success when doing nothing in + pam_setcred because the stack has already been frozen after the + authentication step, and returning an error causes the stack to fail + on some other Linux PAM implementations. Thanks, Ian Ward Comfort. + + In the second pass through the password group, prompt for the new + password and store it in the PAM data even if the user is being + ignored. This is required to allow this module to be stacked with + another module that uses use_authtok. Without this behavior, the + second module won't be able to work for any ignored user since it will + see no saved password and use_authtok will reject the password change. + + Fix return status from pam_sm_acct_mgmt if we were unable to retrieve + PAM_USER. + + Log successful authentications to syslog with priority LOG_INFO, + including the Kerberos principal used for authentication. + + Log failed authentication to syslog with priority LOG_NOTICE, + including roughly the same additional information that the Linux PAM + pam_unix logs by default. + + Use pam_syslog for logging where available. This means pam-krb5 log + messages will look like all other log messages for Linux PAM modules + on Linux. Change the format of log messages on all platforms to + hopefully be somewhat clearer. + + Rationalize logging. The module should now follow the recommendations + of the Linux PAM Module Writers' Guide for log levels. More errors + are logged at LOG_ERR instead of LOG_DEBUG, and system resource errors + are now logged at LOG_CRIT instead of LOG_ERR. + + Add additional error and debug logging in places where significant + actions or failures may happen without previously being logged. Also + add failure information from PAM or Kerberos libraries to messages + where appropriate. + + Add replacement snprintf, vsnprintf, and mkstemp functions for + pointless portability to ancient systems. + +pam-krb5 4.0 (2009-11-13) + + UPGRADE WARNING: If you were using pam_krb5 with the use_authtok + parameter in the password group, you will need to add use_first_pass + to your configuration to keep the same behavior. See below for + details. + + UPGRADE WARNING: If you used the use_authtok parameter in the + authentication group, you should change it to force_first_pass. + + Previous versions of this module incorrectly implemented the standard + use_authtok parameter. use_authtok applies only to the password group + and says to use the new password stored in the PAM data rather than + prompting for a new password. It doesn't imply anything about where + to obtain the old password, but it was implemented as requiring both + the old and new password be in the PAM stack already. This doesn't + work when stacked with pam_cracklib. Change use_authtok to have the + correct meaning, which means that password group configurations may + need to add use_first_pass to use_authtok to get the desired behavior. + + use_first_pass and try_first_pass no longer affect how the new + password is obtained during password changes. To use a password + obtained by a previous module, use use_authtok instead. + + A new option, force_first_pass, is now supported for both the + authentication and password groups. It tells the module to always get + the user's current password from the PAM data and fail without + prompting if it isn't already set. This is the meaning that + use_authtok previously had for the current password. + + use_authtok no longer has any meaning for the authentication stack. + Use force_first_pass instead, which does the same as use_authtok used + to do. use_authtok will be temporarily converted to force_first_pass + in the authentication group and log a diagnostic, but this will be + removed in the future. + + Stop returning PAM_IGNORE from pam_setcred if the user is ignored or + didn't log in via Kerberos and instead return PAM_USER_UNKNOWN. This + fixes problems with the Linux PAM library where returning PAM_IGNORE + would cause pam_setcred to fail even if other modules succeeded. + Since pam_authenticate never returned PAM_IGNORE, this change should + not cause any differences in behavior. + + Do not use issetugid on Solaris to determine when to avoid refreshing + the ticket cache named in KRB5CCNAME during pam_setcred. Instead, + compare effective and real UID and GID and permit KRB5CCNAME to be + trusted if they match. This allows setuid screensavers on Solaris to + refresh ticket caches and makes behavior on Solaris match other + platforms. Using issetugid is arguably safer since it protects + programs that switch users via setuid to a user other than the calling + user but still should not trust the original environment, but such + programs are rare in the PAM context and should not be calling + pam_setcred anyway unless the calling user is permitted to generally + act as the target user. Thanks, William Yang. + + Do the same logging in pam_sm_open_session and pam_sm_close_session as + we do with the other functions. This will mean pam_sm_open_session + calls will be logged as pam_sm_open_session, not as pam_sm_setcred as + before. + + pam-krb5 is now built using Automake and Libtool to bring it more in + line with other software packages. This means that it now relies on + Libtool to know how to generate a loadable module rather than + hand-configured linker rules. This may improve portability on some + platforms and may hurt it on other platforms. + + If configured with a prefix of /usr on Linux, use /lib, /lib32, or + /lib64 as an installation path based on the size of an integer in the + compilation environment rather than based on known 64-bit Linux + variants. + + Update to rra-c-util 2.0: + + * Sanity-check the results of krb5-config before proceeding. + * Fall back on manual probing if krb5-config results don't work. + * Don't break if the user clobbers CPPFLAGS at build time. + +pam-krb5 3.15 (2009-07-21) + + Fix a segfault (null pointer dereference) if pam-krb5 is configured + with use_first_pass or use_authtok and there is no password stored in + the PAM stack. Thanks to Jonathan Guthrie for the bug report. + +pam-krb5 3.14 (2009-07-18) + + Return PAM_IGNORE instead of PAM_PERM_DENIED from pam_chauthtok for + ignored users. This allows making the Kerberos PAM module mandatory + for password changes and still falling back to other PAM modules for + ignored users. Thanks, Steve Langasek. + + Always treat the empty password as an authentication failure rather + than passing it to the Kerberos libraries. The Kerberos libraries + may treat it as equivalent to no password and prompt for a password + without our knowledge, leading to the user authenticating with a + different password than the one stored in the PAM stack. This could + cause unexpected problems with some PAM configurations. It's safer + to make the assumption that the empty password is always invalid and + reject it outside of the Kerberos libraries. Thanks, Sanjay Sha. + + Fix error handling if ticket cache initialization fails. + Authentication will still fail, but this avoids a segfault from a + double-free of the ticket cache structure. The most common cause of + this problem was having the attempt to initialize the ticket cache + be blocked by AppArmor. Thanks to Alex Mauer for the report. + + Call krb5_free_error_string correctly, fixing a portability issue + when building against Heimdal. Thanks, Andrew Drake. + + Work around a deficiency in pam_putenv on FreeBSD 7.2 that doesn't + allow deleting environment variables, only setting them to empty + values. Thanks, Andrew Elble. + +pam-krb5 3.13 (2009-02-11) + + SECURITY: When built against MIT Kerberos, if pam_krb5 is called in a + setuid context (effective UID or GID doesn't match the real UID or + GID), use krb5_init_secure_context instead of krb5_init_context. This + ignores environment variable settings for the local Kerberos + configuration and keytab. Previous versions could allow a local + attacker to point a setuid program that used PAM authentication at a + different Kerberos configuration under the attacker's control, + possibly resulting in privilege escalation. Heimdal handles this + logic within the Kerberos libraries and therefore was not affected. + (CVE-2009-0360) + + SECURITY: Disable pam_setcred(PAM_REINITIALIZE_CREDS) for setuid + applications. If pam_krb5 detects this call in a setuid context, it + now logs an error and returns success without doing anything. Solaris + su calls pam_setcred with that option rather than PAM_ESTABLISH_CREDS + after authentication and without wiping the environment, leading + previous versions of pam_krb5 to trust the KRB5CCNAME environment + variable for the ticket cache location. This permitted an attacker to + use previous versions of pam_krb5 to overwrite arbitrary files with + Kerberos credential caches that were left owned by the attacker. + Setuid screen lock programs may also be affected. Discovered by Derek + Chan and reported by Steven Luo. Thanks to Sam Hartman and Jeffrey + Hutzelman for additional analysis. (CVE-2009-0361) + + If a prefix of /usr is requested at configure time, install the PAM + module into /lib/security or /lib64/security on Linux, matching the + standard Linux-PAM module location. Use lib64 instead of lib on + 64-bit SPARC, PowerPC, and S390 Linux as well as x86_64. Patch from + Peter Breitenlohner. + + Fix a build problem when builddir != srcdir introduced in 3.11. Patch + from Peter Breitenlohner. + + Add support for the old Heimdal krb5_get_error_string interface. + Thanks, Chaskiel Grundman. + + Add --with-krb5-include and --with-krb5-lib configure options to allow + more specific setting of paths if necessary. + + If krb5-config isn't available, attempt to determine if the library + directory for the Kerberos libraries is lib32 or lib64 instead of lib + and set LDFLAGS accordingly. Based on an idea from the CMU Autoconf + macros. + +pam-krb5 3.12 (2008-11-13) + + Add alt_auth_map configuration option, which allows mapping of + usernames to alternative Kerberos principals, useful primarily for + using particular instances for access to a given PAM-authenticated + service. Also added force_alt_auth and only_alt_auth options to + control when alternative Kerberos principals are used. Patch from + Booker Bense. + + Fix incorrect error handling for bad .k5login ownership when + search_k5login is set, leading to a NULL pointer dereference and a + segfault. Thanks, Andrew Deason. + + Fix double-free of the ticket cache structure if creation of the + ticket cache in the session module fails. Thanks, Jens Jorgensen. + + Log all syslog messages to LOG_AUTHPRIV, or LOG_AUTH if the system + doesn't define LOG_AUTHPRIV. Thanks, Mark Painter. + + Fix portability to AIX's bundled Kerberos. Thanks, Markus Moeller. + + When debugging is enabled, log an exit status of PAM_IGNORE as ignore + rather than failure. + + Document that pam-krb5 must be listed in the session group as well as + the auth group for interactive logins or OpenSSH won't set up the + user's credential cache properly. + + Document adding ignore=ignore to complex [] action configuration for + the session and account groups since the module now returns PAM_IGNORE + instead of PAM_SUCCESS for accounts that didn't use Kerberos. + +pam-krb5 3.11 (2008-07-10) + + pam_setcred, pam_open_session, and pam_acct_mgmt now return PAM_IGNORE + for ignored users or non-Kerberos logins rather than PAM_SUCCESS. + This return code tells the PAM library to continue as if the module + were not present in the configuration and allows sufficient to be + meaningful for pam-krb5 in account and session groups. + pam_authenticate continues to return failure for ignored users; + PAM_IGNORE would arguably be more correct, but increases the risk of + security holes through incorrect configuration. + + Support correct password expiration handling according to the PAM + standard (returning success from pam_authenticate and an error from + pam_acct_mgmt and completing the authentication after pam_chauthotk). + This is not the default since it opens security holes with broken + applications that don't call pam_acct_mgmt or ignore its exit status. + To enable it, set the PAM option defer_pwchange for applications known + to make the correct PAM calls and check return codes. + + Add a new option to attempt change of expired passwords during + pam_authenticate if Kerberos authentication returns a password expired + error. Normally, the Kerberos library will do this for you, but some + Kerberos libraries (notably Solaris) disable that code. This option + allows simulation of the normal Kerberos library behavior on those + platforms. + + Work around an apparent Heimdal bug when krb5_free_cred_contents is + called on an all-zero credential structure. It's not clear what's + going on here and the Heimdal code looks correct, but avoiding the + call fixes the problem. + + Warn if more than one of use_authtok, use_first_pass, and + try_first_pass is set and use the strongest of the one set. + + Remove the workaround for versions of MIT Kerberos that didn't + initialize a krb5_get_init_creds_opt structure on opt_alloc. This bug + was only present in early versions of 1.6; the correct fix is to + upgrade. + + Add an additional header check for AIX's bundled Kerberos. + + If KRB5_CONFIG was explicitly set in the environment, don't use a + different krb5-config based on --with-krb5. If krb5-config isn't + executable, don't use it. This allows one to force library probing by + setting KRB5_CONFIG to point to a nonexistent file. + + Sanity-check the results of krb5-config before proceeding and error + out in configure if they don't work. + + For Kerberos libraries without krb5-config, also check for networking + libraries (-lsocket and friends) before checking for Kerberos + libraries in case shared library dependencies are broken. + + Fix Autoconf syntax error when probing for libkrb5support. Thanks, + Mike Garrison. + + Set an explicit visibility of hidden for all internal functions at + compile time if gcc is used to permit better optimization. Hide all + functions except the official interfaces using a version script on + Linux. This protects against leaking symbols into the application + namespace and provides some mild optimization benefit. + + Fix the probing of PAM headers for const on Mac OS X. This will + suppress some harmless compiler warnings there. Thanks, Markus + Moeller. + +pam-krb5 3.10 (2007-12-28) + + The workaround for krb5_get_init_creds_opt_alloc problems in MIT + Kerberos 1.6 broke PKINIT support with Heimdal. Only apply that + workaround when building against the MIT Kerberos libraries. Thanks + to Jaakko Pero for the detailed report. + + If no_ccache is set, always exit successfully from pam_setcred or + pam_open_session, even if we couldn't retrieve module data. Thanks, + Markus Moeller. + + When keytab is set, properly handle failure to create a keytab cursor + and don't assume that the cursor is valid. Thanks, Markus Moeller. + + Define _ALL_SOURCE on AIX to get prototypes for snprintf. + + Add additional portability glue and Autoconf probes to support + building against the version of Kerberos bundled with AIX. Support + for this should be considered alpha in this release. Thanks to Markus + Moeller for the initial patch. + +pam-krb5 3.9 (2007-11-12) + + If use_authtok is set, fail even if we can retrieve the stored PAM + password if that password is set to NULL. Apparently that can happen + in some cases, such as with pam_cracklib. Thanks to Christian Holler + for the diagnosis and a patch. + + Add a new clear_on_fail option for the password group. If set, when a + password change fails, set PAM_AUTHTOK to NULL so that subsequent + modules in the PAM stack with use_authtok set will also fail. Just + returning failure doesn't abort the stack on the second pass when + actual password changes are made. This is not the default since it + interferes with other desirable PAM configurations. It's useful + primarily when using the PAM stack to synchronize passwords between + multiple environments. Thanks to Christian Holler and Tomas Mraz for + the analysis. + + Fix portability issues with Heimdal, versions of PAM that don't + provide pam_modutil_getpwnam, and compiler warnings when building + PKINIT support. Thanks, Martin von Gagern. + + Fix parsing of the keytab PAM option. Thanks, Markus Moeller. + + Return PAM_AUTHINFO_UNAVAIL instead of PAM_AUTH_ERR when unable to + resolve the Kerberos realm. Thanks, Frank Cornelissen. + + Add a new debugging section to the README. + +pam-krb5 3.8 (2007-09-30) + + krb5_get_init_creds_opt_alloc doesn't initialize the returned + structure with the default flags in MIT Kerberos 1.6, which meant that + users with expired passwords were not being prompted to change their + password but just rejected. Fixed by always calling _init before + setting the credential flags, regardless of the provenance of the opt + structure. Thanks, Michael Richters. + + Fix configure and Makefile glue so that Mac OS X and HP-UX have a + chance of working (still untested). + + Add a make warnings target with aggressive gcc warning options. Treat + negative minimum UIDs as zero so that UID comparisons can always be + done unsigned. Add casts and unused attributes as needed. + +pam-krb5 3.7 (2007-09-29) + + If given an explicit keytab path to use for credential verification, + use the first principal found in that keytab as the principal for + verification rather than the library default (which is normally the + host/* principal for the local system and may not be found in that + keytab). + + When authenticating, don't store our context data until after + authentication has succeeded. Otherwise, we may destroy the ticket + cache of a previous successful authentication. This bug would only + affect configurations where pam_krb5 was run multiple times with + different settings, such as multiple realms. Thanks to Dave Botsch + for the report. + + Use pam_modutil_getpwnam instead of getpwnam if available for better + thread safety. + + Don't store PAM data unless we're saving a ticket cache. All other + calls use it for is to find the ticket cache, so without a cache it's + pointless and means we run the risk of stomping on ourselves in + multithreaded programs. + + Still canonicalize the PAM user before returning when not saving a + ticket cache. + + Fix determination of linker flags on non-x86_64 Linux. Always link + with -fPIC when using GCC, just in case. + + Add compilation options for Mac OS X and HP-UX (untested). + + Use pam_krb5 instead of ctx for our PAM data name to reduce the + chances of collision. + +pam-krb5 3.6 (2007-09-18) + + When the local user doesn't exist and search_k5login is enabled, fall + back to simple Kerberos authentication just as if the account existed + with no .k5login file. This avoids trying to verify an all-zero + credentials structure, leading to non-expoloitable segfaults on x86_64 + systems. Be more careful in general about setting error codes in the + search_k5login implementation. + + Explicitly clear the forwardable and proxiable options and don't ask + for renewable tickets when getting a ticket for the password changing + service. Otherwise, system-wide defaults and PAM configuration will + apply to those tickets as well and the resulting ticket request may be + rejected based on KDC configuration. Based on a patch by Sergio + Gelato. + + Do username canonicalization earlier so that .k5login checking and + similar work uses the correct username but only change the PAM + username if authentication succeeds. Document that username + canonicalization won't work with unmodified OpenSSH and with several + common PAM modules. Thanks to R. Scott Bailey for the bug report and + analysis. + + Add a prompt_principal option which, if set, causes the PAM module to + prompt the user for the Kerberos principal to use for authentication + before prompting for the password. + + Try to determine whether the PAM headers use const in the prototypes + of such things as pam_get_item and adjust accordingly. This should + address most compiler warnings on Solaris. Thanks, Markus Moeller. + + Change lib to lib64 on x86_64 Linux to allow for the magical $ISA + parameter in Red Hat's PAM configuration. Hopefully this won't cause + problems elsewhere. + + Support DESTDIR for make install. + +pam-krb5 3.5 (2007-04-10) + + Don't try to chown non-FILE ticket caches, which among other things + breaks using pam-krb5 with Heimdal KCM caches. Thanks, Jeremy + Jackson. + + When logging session deletion via pam_setcred or pam_close_session, + don't look for the username in the PAM context after it's been freed. + Thanks, Markus Moeller. + + Map more Kerberos status codes to PAM status codes for authentication + errors. + +pam-krb5 3.4 (2007-01-28) + + More compilation fixes for Heimdal 0.7, which has a pkinit function + but takes a different number of arguments. Thanks, Morgan LEFIEUX. + + Never call error_message directly on Heimdal. krb5_get_err_text can + cope with a NULL context and krb5-config on Heimdal doesn't include + -lcom_err. + + Handle a NULL return from krb5_get_error_message, since that seems + possible in some edge cases. + + Call krb5_get_error_message on Heimdal as well if it's available, + since it's supported by the 0.8 release candidates. + +pam-krb5 3.3 (2007-01-24) + + Support the new MIT Kerberos error message functions. + + Fix compilation errors in the Heimdal PKINIT support and don't be + confused by a similar function in the MIT Kerberos PKINIT branch. + Thanks to Douglas E. Engert for the testing and patch. + + Fix compilation errors with Heimdal 0.7, which has some of the PKINIT + functions but doesn't define the same error codes. Thanks, Morgan + LEFIEUX. + + Initial support for the MIT Kerberos PKINIT branch, which uses a + different mechanism for configuring PKINIT support than Heimdal. Also + support configuration of general preauth parameters for the MIT + preauth plugin system via the preauth_opt option. Thanks to Douglas + E. Engert for the initial patch. + + If use_pkinit is set in the PAM configuration and PKINIT isn't + available or cannot be forced, always fail authentication. + +pam-krb5 3.2 (2007-01-16) + + This release fixes numerous bugs all identified by Douglas E. Engert + while testing with Heimdal and PKINIT support. Thank you! + + Rewrite the code to drop the credlist data structure since we only + ever have one set of credentials, allocate new krb5_creds objects, and + do proper memory management, which should plug some memory leaks of + the contents of krb5_creds objects. + + Probe for the correct Heimdal function to set default initial + credential options. + + Prefix the default cache path with "FILE:" to make the cache type + explicit. + + Fix installation of the manual page when building from a different + directory than the source directory. + + Fix several compilation errors with the PKINIT support with Heimdal + 0.8rc1 or later. This code should still be considered alpha-quality. + +pam-krb5 3.1 (2007-01-03) + + Fix an infinite loop with failed Kerberos authentication and a doubled + colon that causes a syntax error with some compilers. Thanks, Markus + Moeller. + + Move the check for users we should ignore to pam_sm_authenticate + from pamk5_password_auth so that it's consistently done in the API + function. This also avoids bogus log messages when authenticating as + an ignored user with debug enabled. + +pam-krb5 3.0 (2006-12-18) + + Add preliminary PKINIT support, contributed by Douglas E. Engert. + I reorganized and refactored the code extensively and it therefore may + not compile; until it has received more testing, it should be + considered alpha-quality. Currently, PKINIT support requires Heimdal + 0.8rc1 or later. + + Add a keytab configuration option to use a different keytab for + initial credential validation. + + Add a ticket_lifetime configuration option to set the lifetime of + obtained credentials. + + Add the banner and expose_account configuration options, which control + the prompts for authentication and password changing. Provide more + informative prompts when changing passwords. + + Work around a bug in MIT Kerberos prior to 1.4 causing the library to + cache the default realm and assume a particular realm even if the + default realm is later changed. This bug prevented running two + instances of pam-krb5 with different realm settings in the same PAM + stack. Thanks, Dave Botsch. + + Honor PAM_SILENT when the Kerberos library prompts for more + information, passing to the application only prompts. + + If PAM_USER is set to a fully-qualified principal that the Kerberos + library can map to a local account name, reset PAM_USER to that local + account name after authentication. + + Avoid memory leaks in the Kerberos prompter by freeing the PAM + response strings. We were already doing this elsewhere and the world + didn't end, so assume that it's safe for the PAM module to do this. + Also avoid memory leaks in some unusual error conditions. + + Return unknown user rather than internal error when attempting + authentication of a user we're supposed to ignore. + + When debug is enabled, report the principal for which we're attempting + authentication to help catch realm configuration errors. + + Document the broken behavior of old versions of OpenSSH, which tell + PAM to refresh credentials rather than opening a session. Thanks, + Michael C. Garrison. + + Add a link to the distribution page to the pam-krb5 man page. + + Extensive refactoring and reorganization of the code. + +pam-krb5 2.6 (2006-11-28) + + Don't assume the pointer set by pam_get_user is usable over the life + of the PAM module; instead, save a local copy. + + Avoid a use of already freed memory when debugging is enabled. + + Use __func__ instead of __FUNCTION__ and provide a fallback for older + versions of gcc and for systems that support neither. Should fix + compilation issues with Sun's C compiler. + + On platforms where we know the appropriate compiler flags, try to + build the module so that symbols are resolved within the module in + preference to any externally available symbols. Also add the + hopefully correct compiler flags for Sun's C compiler. + +pam-krb5 2.5 (2006-11-03) + + Don't free the results of pam_get_item(PAM_AUTHTOK) when changing + passwords. Thanks, Arne Nordmark. + + Be a bit more thorough when checking authorization in + pam_sm_acct_mgmt. Re-retrieve the value of user in case the + application changed it, and if we have a ticket cache (we may not even + after a successful authentication if no_ccache was specified), + retrieve the principal from it rather than using the principal from + the context. + + Overwrite passwords with 0 before freeing them, just out of paranoia + (and because PAM also does this internally). + +pam-krb5 2.4 (2006-10-05) + + Fix compilation problems with Heimdal. Thanks, Matthijs Mohlmann and + Douglas Engert. + + Check for memory allocation failures when parsing PAM options rather + than segfaulting. + + Fix several places where an uninitialized context could have been + passed into the argument parsing function. + + Refactor the code to read configuration from krb5.conf to be easier + to read and understand. Parse renew_lifetime immediately and always + report an error rather than deferring time parsing until acquiring + tickets. + + Log errors (not just authentication failures) at the LOG_ERR level + to match (some of) the recommendations of the Linux PAM documentation. + + Log an error when an unknown option is passed via the PAM + configuration. + +pam-krb5 2.3 (2006-09-03) + + Fix the interface between the Kerberos prompting function and the + PAM conversation function on Linux. Prior to this fix, the PAM module + would only work on Solaris if Kerberos passed multiple prompts, which + happens when an account requires a password change. Solaris and Linux + PAM implementations expect a different structure of pam_message + structs in the conversation function; use a workaround to cater to + both of them. Based on a patch by Joachim Keltsch. + + Implement retain_after_close, which specifies that the PAM module + should never destroy the user's ticket cache, even on session end. + + Adjust for the differences in Solaris's PAM libraries: Include + pam_appl.h everywhere for structure and type definitions, and add + portability workarounds for the return statuses missing from the + Solaris implementation. + +pam-krb5 2.2 (2006-08-28) + + Allow the default realm to be overridden in the PAM options. + + Use the realm, default or otherwise, when reading options from + krb5.conf so that realm-specific sections in [appdefaults] work + correctly. + + Update the build and installation documentation for the new + Autoconf-based build system. This should have been in the last + release but was missed. + + Initialize ticket options correctly when built with Heimdal. + + Fix a typo that caused the Heimdal support not to compile. Thanks, + Matthijs Mohlmann. + +pam-krb5 2.1 (2006-08-26) + + Strip off a FILE: prefix from the cache path before creating it in + case the user set ccache or ccache_dir with a cache type prefix. + Thanks to Björn Torkelsson for the patch. + + Added an Autoconf script to distinguish between Heimdal and MIT + Kerberos and take care of other portability issues. Rewrote the + Makefile accordingly. + + Added portability and error reporting fixes for Heimdal, thanks to + Matthijs Mohlmann. + +pam-krb5 2.0 (2006-08-11) + + Always use a disk cache for temporary storage of credentials between + authentication and setcred or session initialization. This allows the + module to work correctly with OpenSSH ChallengeResponseAuthentication. + + Add support for some PAM options that were supported by the + Sourceforge K5 PAM module, most notably minimum_uid and + renew_lifetime. + + Support setting many PAM options from krb5.conf as well as on the PAM + command line, using the same application section as the Sourceforge + PAM module. Use the profile reading functions provided by the + Kerberos libraries. + + Add support for use_authtok, which is like use_first_pass except that + it will never prompt even if no password is currently set. + + Add a search_k5login option to check the user's password against every + principal listed in .k5login, to support use of this module to + authenticate user access to shared accounts. + + Add an ignore_k5login option that bypasses all checks of .k5login + files entirely and relies solely on krb5_aname_to_localname checks. + + Re-add the ccache option to specify the exact file name of the ticket + cache, and allow for randomization using mkstemp even when this option + is used. + + Only call krb5_kuserok (the .k5login check) when the account to which + the user is authenticating is a local account. It's up to the + application to handle authorization checks for non-local accounts. + + Support preliminary checks for password changing by using that to + obtain the user's current credentials. Correctly handle saved + passwords from previous authentications or password changes when + changing passwords, and correctly set the saved passwords for + subsequent password changes in the PAM stack. + + Only initialize the ticket cache once, no matter how many times + setcred is called. This saves duplicate work and works around a bug + in X.org xdm that otherwise causes it to lose the PAM environment. + + When reinitializing a ticket cache, never reinitialize the temporary + cache created by the authentication call. Instead, fall back to the + default ticket cache name if KRB5CCNAME isn't set. + + Improve support for no_ccache. Now, it doesn't even generate a + temporary ticket cache during authentication but only uses an + in-memory credential list. + + Do user ticket validation using the standard Kerberos library call + rather than rolling our own code. This means that the user can now + set options in krb5.conf to control whether that call should fail if + the local keytab isn't readable or contains no usable keys. + + Completely rewrite the man page. Clean it up and make it more + readable and fully document all of the options. Also rewrite the + README file and clean up the rest of the package documentation. + + Don't create a ticket cache until after successful authentication. + + Understand the FILE: prefix to Kerberos ticket cache names and compare + and chown ticket caches properly with that prefix. + + Add a trailing nul to the password in the Kerberos prompter function, + since some code relies on it being there. + + Review the return status of each PAM function and ensure that we only + return failure statuses that are supported for that function. + + Rename all internal functions with a pamk5_* prefix to avoid + conflicting with any application or system library functions. + + Eliminate global variables in the PAM module and do a better job at + cleaning up memory usage. There are still a few places where the PAM + conversation functions may leak memory due to an incomplete + specification in the PAM API on who should free what memory. + + The logging messages produced when debug is set should now be more + consistent and more complete. + +pam-krb5 1.2 (2005-09-27) + + Don't reinitialize the ticket cache if the old and new cache have the + same name, since otherwise we end up destroying it. + + Always set KRB5CCNAME, even when reinitializing. + + When reinitializing, look for the ticket cache in the saved context + even if KRB5CCNAME isn't set. OpenSSH calls it this way. + + Drop the ccache option and add ccache_dir instead, which only + specifies the directory for ticket caches and is therefore easier to + implement. + +pam-krb5 1.1 (2005-08-31) + + Add support for reinitialization/refreshing of credentials in + pam_sm_setcred. + + Set PAM_AUTHTOK and PAM_OLDAUTHTOK when authenticating to better + support stacking this module with others. + + Add an ignore_root option to not do anything when the account to which + the user is authenticating is root. This allows one to log in via + console as root even when the network is down (thereby breaking the + PAM module in ways that login doesn't like due to timeouts in the + Kerberos libraries). + + Store the entire context structure in PAM's memory rather than just + the name of the ticket cache so that we can pass around more data to + ourself. + + Bring errors more in line with the official PAM specification. + + Move prompt generation into the PAM module rather than letting the + Kerberos library generate the prompt. This way we don't leak + principal information to the caller, and the non-standard prompt also + broke some applications like gksudo. + + Support session management and destruction of the ticket cache on + close of session. + + Don't require that the user have a local account on the system. + + Include the user UID in the default ticket cache name so that rpc.gssd + and similar programs can find it. diff --git a/README b/README new file mode 100644 index 000000000000..3b7cb5c886dc --- /dev/null +++ b/README @@ -0,0 +1,641 @@ + pam-krb5 4.11 + (PAM module for Kerberos authentication) + Maintained by Russ Allbery + + Copyright 2005-2010, 2014-2015, 2017, 2020-2021 Russ Allbery + . Copyright 2009-2011 The Board of Trustees of the + Leland Stanford Junior University. Copyright 2005 Andres Salomon + . Copyright 1999-2000 Frank Cusack + . This software is distributed under a BSD-style + license. Please see the section LICENSE below for more information. + +BLURB + + pam-krb5 is a Kerberos PAM module for either MIT Kerberos or Heimdal. + It supports ticket refreshing by screen savers, configurable + authorization handling, authentication of non-local accounts for network + services, password changing, and password expiration, as well as all the + standard expected PAM features. It works correctly with OpenSSH, even + with ChallengeResponseAuthentication and PrivilegeSeparation enabled, + and supports extensive configuration either by PAM options or in + krb5.conf or both. PKINIT is supported with recent versions of both MIT + Kerberos and Heimdal and FAST is supported with recent MIT Kerberos. + +DESCRIPTION + + pam-krb5 provides a Kerberos PAM module that supports authentication, + user ticket cache handling, simple authorization (via .k5login or + checking Kerberos principals against local usernames), and password + changing. It can be configured through either options in the PAM + configuration itself or through entries in the system krb5.conf file, + and it tries to work around PAM implementation flaws in commonly-used + PAM-enabled applications such as OpenSSH and xdm. It supports both + PKINIT and FAST to the extent that the underlying Kerberos libraries + support these features. + + This is not the Kerberos PAM module maintained on Sourceforge and used + on Red Hat systems. It is an independent implementation that, if it + ever shared any common code, diverged long ago. It supports some + features that the Sourceforge module does not (particularly around + authorization), and does not support some options (particularly ones not + directly related to Kerberos) that it does. This module will never + support Kerberos v4 or AFS. For an AFS session module that works with + this module (or any other Kerberos PAM module), see pam-afs-session [1]. + + [1] https://www.eyrie.org/~eagle/software/pam-afs-session/ + + If there are other options besides AFS and Kerberos v4 support from the + Sourceforge PAM module that you're missing in this module, please let me + know. + +REQUIREMENTS + + Either MIT Kerberos (or Kerberos implementations based on it) or Heimdal + are supported. MIT Keberos 1.3 or later may be required; this module + has not been tested with earlier versions. + + For PKINIT support, Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or + later are required. Earlier MIT Kerberos 1.6 releases have a bug in + their handling of PKINIT options. MIT Kerberos 1.12 or later is + required to use the use_pkinit PAM option. + + For FAST (Flexible Authentication Secure Tunneling) support, MIT + Kerberos 1.7 or higher is required. For anonymous FAST support, + anonymous authentication (generally anonymous PKINIT) support is + required in both the Kerberos libraries and in the local KDC. + + This module should work on Linux and build with gcc or clang. It may + still work on Solaris and build with the Sun C compiler, but I have only + tested it on Linux recently. There is beta-quality support for the AIX + NAS Kerberos implementation that has not been tested in years. Other + PAM implementations will probably require some porting, although + untested build system support is present for FreeBSD, Mac OS X, and + HP-UX. I personally can only test on Linux and rely on others to report + problems on other operating systems. + + Old versions of OpenSSH are known to call pam_authenticate followed by + pam_setcred(PAM_REINITIALIZE_CRED) without first calling + pam_open_session, thereby requesting that an existing ticket cache be + renewed (similar to what a screensaver would want) rather than + requesting a new ticket cache be created. Since this behavior is + indistinguishable at the PAM level from a screensaver, pam-krb5 when + used with these old versions of OpenSSH will refresh the ticket cache of + the OpenSSH daemon rather than setting up a new ticket cache for the + user. The resulting ticket cache will have the correct permissions + (this is not a security concern), but will not be named correctly or + referenced in the user's environment and will be overwritten by the next + user login. The best solution to this problem is to upgrade OpenSSH. + I'm not sure exactly when this problem was fixed, but at the very least + OpenSSH 4.3 and later do not exhibit it. + + To bootstrap from a Git checkout, or if you change the Automake files + and need to regenerate Makefile.in, you will need Automake 1.11 or + later. For bootstrap or if you change configure.ac or any of the m4 + files it includes and need to regenerate configure or config.h.in, you + will need Autoconf 2.64 or later. Perl is also required to generate + manual pages from a fresh Git checkout. + +BUILDING AND INSTALLATION + + You can build and install pam-krb5 with the standard commands: + + ./configure + make + make install + + If you are building from a Git clone, first run ./bootstrap in the + source directory to generate the build files. make install will + probably have to be done as root. Building outside of the source + directory is also supported, if you wish, by creating an empty directory + and then running configure with the correct relative path. + + The module will be installed in /usr/local/lib/security by default, but + expect to have to override this using --libdir. The correct + installation path for PAM modules varies considerably between systems. + The module will always be installed in a subdirectory named security + under the specified value of --libdir. On Red Hat Linux, for example, + --libdir=/usr/lib64 is appropriate to install the module into the system + PAM directory. On Debian's amd64 architecture, + --libdir=/usr/lib/x86_64-linux-gnu would be correct. + + Normally, configure will use krb5-config to determine the flags to use + to compile with your Kerberos libraries. To specify a particular + krb5-config script to use, either set the PATH_KRB5_CONFIG environment + variable or pass it to configure like: + + ./configure PATH_KRB5_CONFIG=/path/to/krb5-config + + If krb5-config isn't found, configure will look for the standard + Kerberos libraries in locations already searched by your compiler. If + the the krb5-config script first in your path is not the one + corresponding to the Kerberos libraries you want to use, or if your + Kerberos libraries and includes aren't in a location searched by default + by your compiler, you need to specify a different Kerberos installation + root via --with-krb5=PATH. For example: + + ./configure --with-krb5=/usr/pubsw + + You can also individually set the paths to the include directory and the + library directory with --with-krb5-include and --with-krb5-lib. You may + need to do this if Autoconf can't figure out whether to use lib, lib32, + or lib64 on your platform. + + To not use krb5-config and force library probing even if there is a + krb5-config script on your path, set PATH_KRB5_CONFIG to a nonexistent + path: + + ./configure PATH_KRB5_CONFIG=/nonexistent + + krb5-config is not used and library probing is always done if either + --with-krb5-include or --with-krb5-lib are given. + + Pass --enable-silent-rules to configure for a quieter build (similar to + the Linux kernel). Use make warnings instead of make to build with full + compiler warnings (requires either GCC or Clang and may require a + relatively current version of the compiler). + + You can pass the --enable-reduced-depends flag to configure to try to + minimize the shared library dependencies encoded in the binaries. This + omits from the link line all the libraries included solely because other + libraries depend on them and instead links the programs only against + libraries whose APIs are called directly. This will only work with + shared libraries and will only work on platforms where shared libraries + properly encode their own dependencies (this includes most modern + platforms such as all Linux). It is intended primarily for building + packages for Linux distributions to avoid encoding unnecessary shared + library dependencies that make shared library migrations more difficult. + If none of the above made any sense to you, don't bother with this flag. + +TESTING + + pam-krb5 comes with a comprehensive test suite, but it requires some + configuration in order to test anything other than low-level utility + functions. For the full test suite, you will need to have a running KDC + in which you can create two test accounts, one with admin access to the + other. Using a test KDC environment, if you have one, is recommended. + + Follow the instructions in tests/config/README to configure the test + suite. + + Now, you can run the test suite with: + + make check + + If a test fails, you can run a single test with verbose output via: + + tests/runtests -o + + Do this instead of running the test program directly since it will + ensure that necessary environment variables are set up. + + The default libkadm5clnt library on the system must match the + implementation of your KDC for the module/expired test to work, since + the two kadmin protocols are not compatible. If you use the MIT library + against a Heimdal server, the test will be skipped; if you use the + Heimdal library against an MIT server, the test suite may hang. + + Several module/expired tests are expected to fail with Heimdal 1.5 due + to a bug in Heimdal with reauthenticating immediately after a + library-mediated password change of an expired password. This is fixed + in later releases of Heimdal. + + To run the full test suite, Perl 5.10 or later is required. The + following additional Perl modules will be used if present: + + * Test::Pod + * Test::Spelling + + All are available on CPAN. Those tests will be skipped if the modules + are not available. + + To enable tests that don't detect functionality problems but are used to + sanity-check the release, set the environment variable RELEASE_TESTING + to a true value. To enable tests that may be sensitive to the local + environment or that produce a lot of false positives without uncovering + many problems, set the environment variable AUTHOR_TESTING to a true + value. + +CONFIGURING + + Just installing the module does not enable it or change anything about + your system authentication configuration. To use the module for all + system authentication on Debian systems, put something like: + + auth sufficient pam_krb5.so minimum_uid=1000 + auth required pam_unix.so try_first_pass nullok_secure + + in /etc/pam.d/common-auth, something like: + + session optional pam_krb5.so minimum_uid=1000 + session required pam_unix.so + + in /etc/pam.d/common-session, and something like: + + account required pam_krb5.so minimum_uid=1000 + account required pam_unix.so + + in /etc/pam.d/common-account. The minimum_uid setting tells the PAM + module to pass on any users with a UID lower than 1000, thereby + bypassing Kerberos authentication for the root account and any system + accounts. You normally want to do this since otherwise, if the network + is down, the Kerberos authentication can time out and make it difficult + to log in as root and fix matters. This also avoids problems with + Kerberos principals that happen to match system accounts accidentally + getting access to those accounts. + + Be sure to include the module in the session group as well as the auth + group. Without the session entry, the user's ticket cache will not be + created properly for ssh logins (among possibly others). + + If your users should normally all use Kerberos passwords exclusively, + putting something like: + + password sufficient pam_krb5.so minimum_uid=1000 + password required pam_unix.so try_first_pass obscure md5 + + in /etc/pam.d/common-password will change users' passwords in Kerberos + by default and then only fall back on Unix if that doesn't work. (You + can make this tighter by using the more complex new-style PAM + configuration.) If you instead want to synchronize local and Kerberos + passwords and change them both at the same time, you can do something + like: + + password required pam_unix.so obscure sha512 + password required pam_krb5.so use_authtok minimum_uid=1000 + + If you have multiple environments that you want to synchronize and you + don't want password changes to continue if the Kerberos password change + fails, use the clear_on_fail option. For example: + + password required pam_krb5.so clear_on_fail minimum_uid=1000 + password required pam_unix.so use_authtok obscure sha512 + password required pam_smbpass.so use_authtok + + In this case, if pam_krb5 cannot change the password (due to password + strength rules on the KDC, for example), it will clear the stored + password (because of the clear_on_fail option), and since pam_unix and + pam_smbpass are both configured with use_authtok, they will both fail. + clear_on_fail is not the default because it would interfere with the + more common pattern of falling back to local passwords if the user + doesn't exist in Kerberos. + + If you use a more complex configuration with the Linux PAM [] syntax for + the session and account groups, note that pam_krb5 returns a status of + ignore, not success, if the user didn't log on with Kerberos. You may + need to handle that explicitly with ignore=ignore in your action list. + + There are many, many other possibilities. See the Linux PAM + documentation for all the configuration options. + + On Red Hat systems, modify /etc/pam.d/system-auth instead, which + contains all of the configuration for the different stacks. + + You can also use pam-krb5 only for specific services. In that case, + modify the files in /etc/pam.d for that particular service to use + pam_krb5.so for authentication. For services that are using passwords + over TLS to authenticate users, you may want to use the ignore_k5login + and no_ccache options to the authenticate module. .k5login + authorization is only meaningful for local accounts and ticket caches + are usually (although not always) only useful for interactive sessions. + + Configuring the module for Solaris is both simpler and less flexible, + since Solaris (at least Solaris 8 and 9, which are the last versions of + Solaris with which this module was extensively tested) use a single + /etc/pam.conf file that contains configuration for all programs. For + console login on Solaris, try something like: + + login auth sufficient /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login auth required /usr/lib/security/pam_unix_auth.so.1 use_first_pass + login account required /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login account required /usr/lib/security/pam_unix_account.so.1 + login session required /usr/local/lib/security/pam_krb5.so retain_after_close minimum_uid=100 + login session required /usr/lib/security/pam_unix_session.so.1 + + A similar configuration could be used for other services, such as ssh. + See the pam.conf(5) man page for more information. When using this + module with Solaris login (at least on Solaris 8 and 9), you will + probably also need to add retain_after_close to the PAM configuration to + avoid having the user's credentials deleted before they are logged in. + + The Solaris Kerberos library reportedly does not support prompting for a + password change of an expired account during authentication. Supporting + password change for expired accounts on Solaris with native Kerberos may + therefore require setting the defer_pwchange or force_pwchange option + for selected login applications. See the description and warnings about + that option in the pam_krb5(5) man page. + + Some configuration options may be put in the krb5.conf file used by your + Kerberos libraries (usually /etc/krb5.conf or /usr/local/etc/krb5.conf) + instead or in addition to the PAM configuration. See the man page for + more details. + + The Kerberos library, via pam-krb5, will prompt the user to change their + password if their password is expired, but when using OpenSSH, this will + only work when ChallengeResponseAuthentication is enabled. Unless this + option is enabled, OpenSSH doesn't pass PAM messages to the user and can + only respond to a simple password prompt. + + If you are using MIT Kerberos, be aware that users whose passwords are + expired will not be prompted to change their password unless the KDC + configuration for your realm in [realms] in krb5.conf contains a + master_kdc setting or, if using DNS SRV records, you have a DNS entry + for _kerberos-master as well as _kerberos. + +DEBUGGING + + The first step when debugging any problems with this module is to add + debug to the PAM options for the module (either in the PAM configuration + or in krb5.conf). This will significantly increase the logging from the + module and should provide a trace of exactly what failed and any + available error information. + + Many Kerberos authentication problems are due to configuration issues in + krb5.conf. If pam-krb5 doesn't work, first check that kinit works on + the same system. That will test your basic Kerberos configuration. If + the system has a keytab file installed that's readable by the process + doing authentication via PAM, make sure that the keytab is current and + contains a key for host/ where is the fully-qualified + hostname. pam-krb5 prevents KDC spoofing by checking the user's + credentials when possible, but this means that if a keytab is present it + must be correct or authentication will fail. You can check the keytab + with klist -k and kinit -k. + + Be sure that all libraries and modules, including PAM modules, loaded by + a program use the same Kerberos libraries. Sometimes programs that use + PAM, such as current versions of OpenSSH, also link against Kerberos + directly. If your sshd is linked against one set of Kerberos libraries + and pam-krb5 is linked against a different set of Kerberos libraries, + this will often cause problems (such as segmentation faults, bus errors, + assertions, or other strange behavior). Similar issues apply to the + com_err library or any other library used by both modules and shared + libraries and by the application that loads them. If your OS ships + Kerberos libraries, it's usually best if possible to build all Kerberos + software on the system against those libraries. + +IMPLEMENTATION NOTES + + The normal sequence of actions taken for a user login is: + + pam_authenticate + pam_setcred(PAM_ESTABLISH_CRED) + pam_open_session + pam_acct_mgmt + + and then at logout: + + pam_close_session + + followed by closing the open PAM session. The corresponding pam_sm_* + functions in this module are called when an application calls those + public interface functions. Not all applications call all of those + functions, or in particularly that order, although pam_authenticate is + always first and has to be. + + When pam_authenticate is called, pam-krb5 creates a temporary ticket + cache in /tmp and sets the PAM environment variable PAM_KRB5CCNAME to + point to it. This ticket cache will be automatically destroyed when the + PAM session is closed and is there only to pass the initial credentials + to the call to pam_setcred. The module would use a memory cache, but + memory caches will only work if the application preserves the PAM + environment between the calls to pam_authenticate and pam_setcred. Most + do, but OpenSSH notoriously does not and calls pam_authenticate in a + subprocess, so this method is used to pass the tickets to the + pam_setcred call in a different process. + + pam_authenticate does a complete authentication, including checking the + resulting TGT by obtaining a service ticket for the local host if + possible, but this requires read access to the system keytab. If the + keytab doesn't exist, can't be read, or doesn't include the appropriate + credentials, the default is to accept the authentication. This can be + controlled by setting verify_ap_req_nofail to true in [libdefaults] in + /etc/krb5.conf. pam_authenticate also does a basic authorization check, + by default calling krb5_kuserok (which uses ~/.k5login if available and + falls back to checking that the principal corresponds to the account + name). This can be customized with several options documented in the + pam_krb5(5) man page. + + pam-krb5 treats pam_open_session and pam_setcred(PAM_ESTABLISH_CRED) as + synonymous, as some applications call one and some call the other. Both + copy the initial credentials from the temporary cache into a permanent + cache for this session and set KRB5CCNAME in the environment. It will + remember when the credential cache has been established and then avoid + doing any duplicate work afterwards, since some applications call + pam_setcred or pam_open_session multiple times (most notably X.Org 7 and + earlier xdm, which also throws away the module settings the last time it + calls them). + + pam_acct_mgmt finds the ticket cache, reads it in to obtain the + authenticated principal, and then does is another authorization check + against .k5login or the local account name as described above. + + After the call to pam_setcred or pam_open_session, the ticket cache will + be destroyed whenever the calling application either destroys the PAM + environment or calls pam_close_session, which it should do on user + logout. + + The normal sequence of events when refreshing a ticket cache (such as + inside a screensaver) is: + + pam_authenticate + pam_setcred(PAM_REINITIALIZE_CRED) + pam_acct_mgmt + + (PAM_REFRESH_CRED may be used instead.) Authentication proceeds as + above. At the pam_setcred stage, rather than creating a new ticket + cache, the module instead finds the current ticket cache (from the + KRB5CCNAME environment variable or the default ticket cache location + from the Kerberos library) and then reinitializes it with the + credentials from the temporary pam_authenticate ticket cache. When + refreshing a ticket cache, the application should not open a session. + Calling pam_acct_mgmt is optional; pam-krb5 doesn't do anything + different when it's called in this case. + + If pam_authenticate apparently didn't succeed, or if an account was + configured to be ignored via ignore_root or minimum_uid, pam_setcred + (and therefore pam_open_session) and pam_acct_mgmt return PAM_IGNORE, + which tells the PAM library to proceed as if that module wasn't listed + in the PAM configuration at all. pam_authenticate, however, returns + failure in the ignored user case by default, since otherwise a + configuration using ignore_root with pam-krb5 as the only PAM module + would allow anyone to log in as root without a password. There doesn't + appear to be a case where returning PAM_IGNORE instead would improve the + module's behavior, but if you know of a case, please let me know. + + By default, pam_authenticate intentionally does not follow the PAM + standard for handling expired accounts and instead returns failure from + pam_authenticate unless the Kerberos libraries are able to change the + account password during authentication. Too many applications either do + not call pam_acct_mgmt or ignore its exit status. The fully correct PAM + behavior (returning success from pam_authenticate and + PAM_NEW_AUTHTOK_REQD from pam_acct_mgmt) can be enabled with the + defer_pwchange option. + + The defer_pwchange option is unfortunately somewhat tricky to implement. + In this case, the calling sequence is: + + pam_authenticate + pam_acct_mgmt + pam_chauthtok + pam_setcred + pam_open_session + + During the first pam_authenticate, we can't obtain credentials and + therefore a ticket cache since the password is expired. But + pam_authenticate isn't called again after pam_chauthtok, so + pam_chauthtok has to create a ticket cache. We however don't want it to + do this for the normal password change (passwd) case. + + What we do is set a flag in our PAM data structure saying that we're + processing an expired password, and pam_chauthtok, if it sees that flag, + redoes the authentication with password prompting disabled after it + finishes changing the password. + + Unfortunately, when handling password changes this way, pam_chauthtok + will always have to prompt the user for their current password again + even though they just typed it. This is because the saved + authentication tokens are cleared after pam_authenticate returns, for + security reasons. We could hack around this by saving the password in + our PAM data structure, but this would let the application gain access + to it (exactly what the clearing is intended to prevent) and breaks a + PAM library guarantee. We could also work around this by having + pam_authenticate get the kadmin/changepw authenticator in the expired + password case and store it for pam_chauthtok, but it doesn't seem worth + the hassle. + +HISTORY AND ACKNOWLEDGEMENTS + + Originally written by Frank Cusack , with the + following acknowledgement: + + Thanks to Naomaru Itoi , Curtis King + , and Derrick Brashear , all + of whom have written and made available Kerberos 4/5 modules. + Although no code in this module is directly from these author's + modules, (except the get_user_info() routine in support.c; derived + from whichever of these authors originally wrote the first module the + other 2 copied from), it was extremely helpful to look over their code + which aided in my design. + + The module was then patched for the FreeBSD ports collection with + additional modifications by unknown maintainers and then was modified by + Joel Kociolek to be usable with Debian GNU/Linux. + + It was packaged by Sam Hartman as the Kerberos v5 PAM module for Debian + and improved and modified by him and later by Russ Allbery to fix bugs + and add additional features. It was then adopted by Andres Salomon, who + added support for refreshing credentials. + + The current distribution is maintained by Russ Allbery, who also added + support for reading configuration from krb5.conf, added many features + for compatibility with the Sourceforge module, commented and + standardized the formatting of the code, and overhauled the + documentation. + + Thanks to Douglas E. Engert for the initial implementation of PKINIT + support. I have since modified and reworked it extensively, so any bugs + or compilation problems are my fault. + + Thanks to Markus Moeller for lots of debugging and multiple patches and + suggestions for improved portability. + + Thanks to Booker Bense for the implementation of the alt_auth_map + option. + + Thanks to Sam Hartman for the FAST support implementation. + +SUPPORT + + The pam-krb5 web page at: + + https://www.eyrie.org/~eagle/software/pam-krb5/ + + will always have the current version of this package, the current + documentation, and pointers to any additional resources. + + For bug tracking, use the issue tracker on GitHub: + + https://github.com/rra/pam-krb5/issues + + However, please be aware that I tend to be extremely busy and work + projects often take priority. I'll save your report and get to it as + soon as I can, but it may take me a couple of months. + +SOURCE REPOSITORY + + pam-krb5 is maintained using Git. You can access the current source on + GitHub at: + + https://github.com/rra/pam-krb5 + + or by cloning the repository at: + + https://git.eyrie.org/git/kerberos/pam-krb5.git + + or view the repository via the web at: + + https://git.eyrie.org/?p=kerberos/pam-krb5.git + + The eyrie.org repository is the canonical one, maintained by the author, + but using GitHub is probably more convenient for most purposes. Pull + requests are gratefully reviewed and normally accepted. + +LICENSE + + The pam-krb5 package as a whole is covered by the following copyright + statement and license: + + Copyright 2005-2010, 2014-2015, 2017, 2020-2021 + Russ Allbery + Copyright 2009-2011 + The Board of Trustees of the Leland Stanford Junior University + Copyright 2005 Andres Salomon + Copyright 1999-2000 Frank Cusack + + 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 General 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. + + Some files in this distribution are individually released under + different licenses, all of which are compatible with the above general + package license but which may require preservation of additional + notices. All required notices, and detailed information about the + licensing of each file, are recorded in the LICENSE file. + + Files covered by a license with an assigned SPDX License Identifier + include SPDX-License-Identifier tags to enable automated processing of + license information. See https://spdx.org/licenses/ for more + information. + + For any copyright range specified by files in this package as YYYY-ZZZZ, + the range specifies every single year in that closed interval. diff --git a/README.md b/README.md new file mode 100644 index 000000000000..e74b6751ceb4 --- /dev/null +++ b/README.md @@ -0,0 +1,665 @@ +# pam-krb5 + +[![Build +status](https://github.com/rra/pam-krb5/workflows/build/badge.svg)](https://github.com/rra/pam-krb5/actions) +[![Debian +package](https://img.shields.io/debian/v/libpam-krb5/unstable)](https://tracker.debian.org/pkg/libpam-krb5) + +Copyright 2005-2010, 2014-2015, 2017, 2020-2021 Russ Allbery +. Copyright 2009-2011 The Board of Trustees of the +Leland Stanford Junior University. Copyright 2005 Andres Salomon +. Copyright 1999-2000 Frank Cusack +. This software is distributed under a BSD-style +license. Please see the section [License](#license) below for more +information. + +## Blurb + +pam-krb5 is a Kerberos PAM module for either MIT Kerberos or Heimdal. It +supports ticket refreshing by screen savers, configurable authorization +handling, authentication of non-local accounts for network services, +password changing, and password expiration, as well as all the standard +expected PAM features. It works correctly with OpenSSH, even with +ChallengeResponseAuthentication and PrivilegeSeparation enabled, and +supports extensive configuration either by PAM options or in krb5.conf or +both. PKINIT is supported with recent versions of both MIT Kerberos and +Heimdal and FAST is supported with recent MIT Kerberos. + +## Description + +pam-krb5 provides a Kerberos PAM module that supports authentication, user +ticket cache handling, simple authorization (via .k5login or checking +Kerberos principals against local usernames), and password changing. It +can be configured through either options in the PAM configuration itself +or through entries in the system krb5.conf file, and it tries to work +around PAM implementation flaws in commonly-used PAM-enabled applications +such as OpenSSH and xdm. It supports both PKINIT and FAST to the extent +that the underlying Kerberos libraries support these features. + +This is not the Kerberos PAM module maintained on Sourceforge and used on +Red Hat systems. It is an independent implementation that, if it ever +shared any common code, diverged long ago. It supports some features that +the Sourceforge module does not (particularly around authorization), and +does not support some options (particularly ones not directly related to +Kerberos) that it does. This module will never support Kerberos v4 or +AFS. For an AFS session module that works with this module (or any other +Kerberos PAM module), see +[pam-afs-session](https://www.eyrie.org/~eagle/software/pam-afs-session/). + +If there are other options besides AFS and Kerberos v4 support from the +Sourceforge PAM module that you're missing in this module, please let me +know. + +## Requirements + +Either MIT Kerberos (or Kerberos implementations based on it) or Heimdal +are supported. MIT Keberos 1.3 or later may be required; this module has +not been tested with earlier versions. + +For PKINIT support, Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or later +are required. Earlier MIT Kerberos 1.6 releases have a bug in their +handling of PKINIT options. MIT Kerberos 1.12 or later is required to use +the use_pkinit PAM option. + +For FAST (Flexible Authentication Secure Tunneling) support, MIT Kerberos +1.7 or higher is required. For anonymous FAST support, anonymous +authentication (generally anonymous PKINIT) support is required in both +the Kerberos libraries and in the local KDC. + +This module should work on Linux and build with gcc or clang. It may +still work on Solaris and build with the Sun C compiler, but I have only +tested it on Linux recently. There is beta-quality support for the AIX +NAS Kerberos implementation that has not been tested in years. Other PAM +implementations will probably require some porting, although untested +build system support is present for FreeBSD, Mac OS X, and HP-UX. I +personally can only test on Linux and rely on others to report problems on +other operating systems. + +Old versions of OpenSSH are known to call `pam_authenticate` followed by +`pam_setcred(PAM_REINITIALIZE_CRED)` without first calling +`pam_open_session`, thereby requesting that an existing ticket cache be +renewed (similar to what a screensaver would want) rather than requesting +a new ticket cache be created. Since this behavior is indistinguishable +at the PAM level from a screensaver, pam-krb5 when used with these old +versions of OpenSSH will refresh the ticket cache of the OpenSSH daemon +rather than setting up a new ticket cache for the user. The resulting +ticket cache will have the correct permissions (this is not a security +concern), but will not be named correctly or referenced in the user's +environment and will be overwritten by the next user login. The best +solution to this problem is to upgrade OpenSSH. I'm not sure exactly when +this problem was fixed, but at the very least OpenSSH 4.3 and later do not +exhibit it. + +To bootstrap from a Git checkout, or if you change the Automake files and +need to regenerate Makefile.in, you will need Automake 1.11 or later. For +bootstrap or if you change configure.ac or any of the m4 files it includes +and need to regenerate configure or config.h.in, you will need Autoconf +2.64 or later. Perl is also required to generate manual pages from a +fresh Git checkout. + +## Building and Installation + +You can build and install pam-krb5 with the standard commands: + +``` + ./configure + make + make install +``` + +If you are building from a Git clone, first run `./bootstrap` in the +source directory to generate the build files. `make install` will +probably have to be done as root. Building outside of the source +directory is also supported, if you wish, by creating an empty directory +and then running configure with the correct relative path. + +The module will be installed in `/usr/local/lib/security` by default, but +expect to have to override this using `--libdir`. The correct +installation path for PAM modules varies considerably between systems. +The module will always be installed in a subdirectory named `security` +under the specified value of `--libdir`. On Red Hat Linux, for example, +`--libdir=/usr/lib64` is appropriate to install the module into the system +PAM directory. On Debian's amd64 architecture, +`--libdir=/usr/lib/x86_64-linux-gnu` would be correct. + +Normally, configure will use `krb5-config` to determine the flags to use +to compile with your Kerberos libraries. To specify a particular +`krb5-config` script to use, either set the `PATH_KRB5_CONFIG` environment +variable or pass it to configure like: + +``` + ./configure PATH_KRB5_CONFIG=/path/to/krb5-config +``` + +If `krb5-config` isn't found, configure will look for the standard +Kerberos libraries in locations already searched by your compiler. If the +the `krb5-config` script first in your path is not the one corresponding +to the Kerberos libraries you want to use, or if your Kerberos libraries +and includes aren't in a location searched by default by your compiler, +you need to specify a different Kerberos installation root via +`--with-krb5=PATH`. For example: + +``` + ./configure --with-krb5=/usr/pubsw +``` + +You can also individually set the paths to the include directory and the +library directory with `--with-krb5-include` and `--with-krb5-lib`. You +may need to do this if Autoconf can't figure out whether to use `lib`, +`lib32`, or `lib64` on your platform. + +To not use `krb5-config` and force library probing even if there is a +`krb5-config` script on your path, set `PATH_KRB5_CONFIG` to a nonexistent +path: + +``` + ./configure PATH_KRB5_CONFIG=/nonexistent +``` + +`krb5-config` is not used and library probing is always done if either +`--with-krb5-include` or `--with-krb5-lib` are given. + +Pass `--enable-silent-rules` to configure for a quieter build (similar to +the Linux kernel). Use `make warnings` instead of `make` to build with +full GCC compiler warnings (requires either GCC or Clang and may require a +relatively current version of the compiler). + +You can pass the `--enable-reduced-depends` flag to configure to try to +minimize the shared library dependencies encoded in the binaries. This +omits from the link line all the libraries included solely because other +libraries depend on them and instead links the programs only against +libraries whose APIs are called directly. This will only work with shared +libraries and will only work on platforms where shared libraries properly +encode their own dependencies (this includes most modern platforms such as +all Linux). It is intended primarily for building packages for Linux +distributions to avoid encoding unnecessary shared library dependencies +that make shared library migrations more difficult. If none of the above +made any sense to you, don't bother with this flag. + +## Testing + +pam-krb5 comes with a comprehensive test suite, but it requires some +configuration in order to test anything other than low-level utility +functions. For the full test suite, you will need to have a running KDC +in which you can create two test accounts, one with admin access to the +other. Using a test KDC environment, if you have one, is recommended. + +Follow the instructions in `tests/config/README` to configure the test +suite. + +Now, you can run the test suite with: + +``` + make check +``` + +If a test fails, you can run a single test with verbose output via: + +``` + tests/runtests -o +``` + +Do this instead of running the test program directly since it will ensure +that necessary environment variables are set up. + +The default libkadm5clnt library on the system must match the +implementation of your KDC for the module/expired test to work, since the +two kadmin protocols are not compatible. If you use the MIT library +against a Heimdal server, the test will be skipped; if you use the Heimdal +library against an MIT server, the test suite may hang. + +Several `module/expired` tests are expected to fail with Heimdal 1.5 due +to a bug in Heimdal with reauthenticating immediately after a +library-mediated password change of an expired password. This is fixed in +later releases of Heimdal. + +To run the full test suite, Perl 5.10 or later is required. The following +additional Perl modules will be used if present: + +* Test::Pod +* Test::Spelling + +All are available on CPAN. Those tests will be skipped if the modules are +not available. + +To enable tests that don't detect functionality problems but are used to +sanity-check the release, set the environment variable `RELEASE_TESTING` +to a true value. To enable tests that may be sensitive to the local +environment or that produce a lot of false positives without uncovering +many problems, set the environment variable `AUTHOR_TESTING` to a true +value. + +## Configuring + +Just installing the module does not enable it or change anything about +your system authentication configuration. To use the module for all +system authentication on Debian systems, put something like: + +``` + auth sufficient pam_krb5.so minimum_uid=1000 + auth required pam_unix.so try_first_pass nullok_secure +``` + +in `/etc/pam.d/common-auth`, something like: + +``` + session optional pam_krb5.so minimum_uid=1000 + session required pam_unix.so +``` + +in `/etc/pam.d/common-session`, and something like: + +``` + account required pam_krb5.so minimum_uid=1000 + account required pam_unix.so +``` + +in `/etc/pam.d/common-account`. The `minimum_uid` setting tells the PAM +module to pass on any users with a UID lower than 1000, thereby bypassing +Kerberos authentication for the root account and any system accounts. You +normally want to do this since otherwise, if the network is down, the +Kerberos authentication can time out and make it difficult to log in as +root and fix matters. This also avoids problems with Kerberos principals +that happen to match system accounts accidentally getting access to those +accounts. + +Be sure to include the module in the session group as well as the auth +group. Without the session entry, the user's ticket cache will not be +created properly for ssh logins (among possibly others). + +If your users should normally all use Kerberos passwords exclusively, +putting something like: + +``` + password sufficient pam_krb5.so minimum_uid=1000 + password required pam_unix.so try_first_pass obscure md5 +``` + +in `/etc/pam.d/common-password` will change users' passwords in Kerberos +by default and then only fall back on Unix if that doesn't work. (You can +make this tighter by using the more complex new-style PAM configuration.) +If you instead want to synchronize local and Kerberos passwords and change +them both at the same time, you can do something like: + +``` + password required pam_unix.so obscure sha512 + password required pam_krb5.so use_authtok minimum_uid=1000 +``` + +If you have multiple environments that you want to synchronize and you +don't want password changes to continue if the Kerberos password change +fails, use the `clear_on_fail` option. For example: + +``` + password required pam_krb5.so clear_on_fail minimum_uid=1000 + password required pam_unix.so use_authtok obscure sha512 + password required pam_smbpass.so use_authtok +``` + +In this case, if `pam_krb5` cannot change the password (due to password +strength rules on the KDC, for example), it will clear the stored password +(because of the `clear_on_fail` option), and since `pam_unix` and +`pam_smbpass` are both configured with `use_authtok`, they will both fail. +`clear_on_fail` is not the default because it would interfere with the +more common pattern of falling back to local passwords if the user doesn't +exist in Kerberos. + +If you use a more complex configuration with the Linux PAM `[]` syntax for +the session and account groups, note that `pam_krb5` returns a status of +ignore, not success, if the user didn't log on with Kerberos. You may +need to handle that explicitly with `ignore=ignore` in your action list. + +There are many, many other possibilities. See the Linux PAM documentation +for all the configuration options. + +On Red Hat systems, modify `/etc/pam.d/system-auth` instead, which +contains all of the configuration for the different stacks. + +You can also use pam-krb5 only for specific services. In that case, +modify the files in `/etc/pam.d` for that particular service to use +`pam_krb5.so` for authentication. For services that are using passwords +over TLS to authenticate users, you may want to use the `ignore_k5login` +and `no_ccache` options to the authenticate module. `.k5login` +authorization is only meaningful for local accounts and ticket caches are +usually (although not always) only useful for interactive sessions. + +Configuring the module for Solaris is both simpler and less flexible, +since Solaris (at least Solaris 8 and 9, which are the last versions of +Solaris with which this module was extensively tested) use a single +`/etc/pam.conf` file that contains configuration for all programs. For +console login on Solaris, try something like: + +``` + login auth sufficient /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login auth required /usr/lib/security/pam_unix_auth.so.1 use_first_pass + login account required /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login account required /usr/lib/security/pam_unix_account.so.1 + login session required /usr/local/lib/security/pam_krb5.so retain_after_close minimum_uid=100 + login session required /usr/lib/security/pam_unix_session.so.1 +``` + +A similar configuration could be used for other services, such as ssh. +See the pam.conf(5) man page for more information. When using this module +with Solaris login (at least on Solaris 8 and 9), you will probably also +need to add `retain_after_close` to the PAM configuration to avoid having +the user's credentials deleted before they are logged in. + +The Solaris Kerberos library reportedly does not support prompting for a +password change of an expired account during authentication. Supporting +password change for expired accounts on Solaris with native Kerberos may +therefore require setting the `defer_pwchange` or `force_pwchange` option +for selected login applications. See the description and warnings about +that option in the pam_krb5(5) man page. + +Some configuration options may be put in the `krb5.conf` file used by your +Kerberos libraries (usually `/etc/krb5.conf` or +`/usr/local/etc/krb5.conf`) instead or in addition to the PAM +configuration. See the man page for more details. + +The Kerberos library, via pam-krb5, will prompt the user to change their +password if their password is expired, but when using OpenSSH, this will +only work when `ChallengeResponseAuthentication` is enabled. Unless this +option is enabled, OpenSSH doesn't pass PAM messages to the user and can +only respond to a simple password prompt. + +If you are using MIT Kerberos, be aware that users whose passwords are +expired will not be prompted to change their password unless the KDC +configuration for your realm in `[realms]` in `krb5.conf` contains a +`master_kdc` setting or, if using DNS SRV records, you have a DNS entry +for `_kerberos-master` as well as `_kerberos`. + +## Debugging + +The first step when debugging any problems with this module is to add +`debug` to the PAM options for the module (either in the PAM configuration +or in `krb5.conf`). This will significantly increase the logging from the +module and should provide a trace of exactly what failed and any available +error information. + +Many Kerberos authentication problems are due to configuration issues in +`krb5.conf`. If pam-krb5 doesn't work, first check that `kinit` works on +the same system. That will test your basic Kerberos configuration. If +the system has a keytab file installed that's readable by the process +doing authentication via PAM, make sure that the keytab is current and +contains a key for `host/` where is the fully-qualified +hostname. pam-krb5 prevents KDC spoofing by checking the user's +credentials when possible, but this means that if a keytab is present it +must be correct or authentication will fail. You can check the keytab +with `klist -k` and `kinit -k`. + +Be sure that all libraries and modules, including PAM modules, loaded by a +program use the same Kerberos libraries. Sometimes programs that use PAM, +such as current versions of OpenSSH, also link against Kerberos directly. +If your sshd is linked against one set of Kerberos libraries and pam-krb5 +is linked against a different set of Kerberos libraries, this will often +cause problems (such as segmentation faults, bus errors, assertions, or +other strange behavior). Similar issues apply to the com_err library or +any other library used by both modules and shared libraries and by the +application that loads them. If your OS ships Kerberos libraries, it's +usually best if possible to build all Kerberos software on the system +against those libraries. + +## Implementation Notes + +The normal sequence of actions taken for a user login is: + +``` + pam_authenticate + pam_setcred(PAM_ESTABLISH_CRED) + pam_open_session + pam_acct_mgmt +``` + +and then at logout: + +``` + pam_close_session +``` + +followed by closing the open PAM session. The corresponding `pam_sm_*` +functions in this module are called when an application calls those public +interface functions. Not all applications call all of those functions, or +in particularly that order, although `pam_authenticate` is always first +and has to be. + +When `pam_authenticate` is called, pam-krb5 creates a temporary ticket +cache in `/tmp` and sets the PAM environment variable `PAM_KRB5CCNAME` to +point to it. This ticket cache will be automatically destroyed when the +PAM session is closed and is there only to pass the initial credentials to +the call to `pam_setcred`. The module would use a memory cache, but +memory caches will only work if the application preserves the PAM +environment between the calls to `pam_authenticate` and `pam_setcred`. +Most do, but OpenSSH notoriously does not and calls `pam_authenticate` in +a subprocess, so this method is used to pass the tickets to the +`pam_setcred` call in a different process. + +`pam_authenticate` does a complete authentication, including checking the +resulting TGT by obtaining a service ticket for the local host if +possible, but this requires read access to the system keytab. If the +keytab doesn't exist, can't be read, or doesn't include the appropriate +credentials, the default is to accept the authentication. This can be +controlled by setting `verify_ap_req_nofail` to true in `[libdefaults]` in +`/etc/krb5.conf`. `pam_authenticate` also does a basic authorization +check, by default calling `krb5_kuserok` (which uses `~/.k5login` if +available and falls back to checking that the principal corresponds to the +account name). This can be customized with several options documented in +the pam_krb5(5) man page. + +pam-krb5 treats `pam_open_session` and `pam_setcred(PAM_ESTABLISH_CRED)` +as synonymous, as some applications call one and some call the other. +Both copy the initial credentials from the temporary cache into a +permanent cache for this session and set `KRB5CCNAME` in the environment. +It will remember when the credential cache has been established and then +avoid doing any duplicate work afterwards, since some applications call +`pam_setcred` or `pam_open_session` multiple times (most notably X.Org 7 +and earlier xdm, which also throws away the module settings the last time +it calls them). + +`pam_acct_mgmt` finds the ticket cache, reads it in to obtain the +authenticated principal, and then does is another authorization check +against `.k5login` or the local account name as described above. + +After the call to `pam_setcred` or `pam_open_session`, the ticket cache +will be destroyed whenever the calling application either destroys the PAM +environment or calls `pam_close_session`, which it should do on user +logout. + +The normal sequence of events when refreshing a ticket cache (such as +inside a screensaver) is: + +``` + pam_authenticate + pam_setcred(PAM_REINITIALIZE_CRED) + pam_acct_mgmt +``` + +(`PAM_REFRESH_CRED` may be used instead.) Authentication proceeds as +above. At the `pam_setcred` stage, rather than creating a new ticket +cache, the module instead finds the current ticket cache (from the +`KRB5CCNAME` environment variable or the default ticket cache location +from the Kerberos library) and then reinitializes it with the credentials +from the temporary `pam_authenticate` ticket cache. When refreshing a +ticket cache, the application should not open a session. Calling +`pam_acct_mgmt` is optional; pam-krb5 doesn't do anything different when +it's called in this case. + +If `pam_authenticate` apparently didn't succeed, or if an account was +configured to be ignored via `ignore_root` or `minimum_uid`, `pam_setcred` +(and therefore `pam_open_session`) and `pam_acct_mgmt` return +`PAM_IGNORE`, which tells the PAM library to proceed as if that module +wasn't listed in the PAM configuration at all. `pam_authenticate`, +however, returns failure in the ignored user case by default, since +otherwise a configuration using `ignore_root` with pam-krb5 as the only +PAM module would allow anyone to log in as root without a password. There +doesn't appear to be a case where returning `PAM_IGNORE` instead would +improve the module's behavior, but if you know of a case, please let me +know. + +By default, `pam_authenticate` intentionally does not follow the PAM +standard for handling expired accounts and instead returns failure from +`pam_authenticate` unless the Kerberos libraries are able to change the +account password during authentication. Too many applications either do +not call `pam_acct_mgmt` or ignore its exit status. The fully correct PAM +behavior (returning success from `pam_authenticate` and +`PAM_NEW_AUTHTOK_REQD` from `pam_acct_mgmt`) can be enabled with the +`defer_pwchange` option. + +The `defer_pwchange` option is unfortunately somewhat tricky to implement. +In this case, the calling sequence is: + +``` + pam_authenticate + pam_acct_mgmt + pam_chauthtok + pam_setcred + pam_open_session +``` + +During the first `pam_authenticate`, we can't obtain credentials and +therefore a ticket cache since the password is expired. But +`pam_authenticate` isn't called again after `pam_chauthtok`, so +`pam_chauthtok` has to create a ticket cache. We however don't want it to +do this for the normal password change (`passwd`) case. + +What we do is set a flag in our PAM data structure saying that we're +processing an expired password, and `pam_chauthtok`, if it sees that flag, +redoes the authentication with password prompting disabled after it +finishes changing the password. + +Unfortunately, when handling password changes this way, `pam_chauthtok` +will always have to prompt the user for their current password again even +though they just typed it. This is because the saved authentication +tokens are cleared after `pam_authenticate` returns, for security reasons. +We could hack around this by saving the password in our PAM data +structure, but this would let the application gain access to it (exactly +what the clearing is intended to prevent) and breaks a PAM library +guarantee. We could also work around this by having `pam_authenticate` +get the `kadmin/changepw` authenticator in the expired password case and +store it for `pam_chauthtok`, but it doesn't seem worth the hassle. + +## History and Acknowledgements + +Originally written by Frank Cusack , with the +following acknowledgement: + +> Thanks to Naomaru Itoi , Curtis King +> , and Derrick Brashear , all of +> whom have written and made available Kerberos 4/5 modules. Although no +> code in this module is directly from these author's modules, (except the +> get_user_info() routine in support.c; derived from whichever of these +> authors originally wrote the first module the other 2 copied from), it +> was extremely helpful to look over their code which aided in my design. + +The module was then patched for the FreeBSD ports collection with +additional modifications by unknown maintainers and then was modified by +Joel Kociolek to be usable with Debian GNU/Linux. + +It was packaged by Sam Hartman as the Kerberos v5 PAM module for Debian +and improved and modified by him and later by Russ Allbery to fix bugs and +add additional features. It was then adopted by Andres Salomon, who added +support for refreshing credentials. + +The current distribution is maintained by Russ Allbery, who also added +support for reading configuration from `krb5.conf`, added many features +for compatibility with the Sourceforge module, commented and standardized +the formatting of the code, and overhauled the documentation. + +Thanks to Douglas E. Engert for the initial implementation of PKINIT +support. I have since modified and reworked it extensively, so any bugs +or compilation problems are my fault. + +Thanks to Markus Moeller for lots of debugging and multiple patches and +suggestions for improved portability. + +Thanks to Booker Bense for the implementation of the `alt_auth_map` +option. + +Thanks to Sam Hartman for the FAST support implementation. + +## Support + +The [pam-krb5 web page](https://www.eyrie.org/~eagle/software/pam-krb5/) +will always have the current version of this package, the current +documentation, and pointers to any additional resources. + +For bug tracking, use the [issue tracker on +GitHub](https://github.com/rra/pam-krb5/issues). However, please be aware +that I tend to be extremely busy and work projects often take priority. +I'll save your report and get to it as soon as I can, but it may take me a +couple of months. + +## Source Repository + +pam-krb5 is maintained using Git. You can access the current source on +[GitHub](https://github.com/rra/pam-krb5) or by cloning the repository at: + +https://git.eyrie.org/git/kerberos/pam-krb5.git + +or [view the repository on the +web](https://git.eyrie.org/?p=kerberos/pam-krb5.git). + +The eyrie.org repository is the canonical one, maintained by the author, +but using GitHub is probably more convenient for most purposes. Pull +requests are gratefully reviewed and normally accepted. + +## License + +The pam-krb5 package as a whole is covered by the following copyright +statement and license: + +> Copyright 2005-2010, 2014-2015, 2017, 2020-2021 +> Russ Allbery +> +> Copyright 2009-2011 +> The Board of Trustees of the Leland Stanford Junior University +> +> Copyright 2005 +> Andres Salomon +> +> Copyright 1999-2000 +> Frank Cusack +> +> 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 +> General 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. + +Some files in this distribution are individually released under different +licenses, all of which are compatible with the above general package +license but which may require preservation of additional notices. All +required notices, and detailed information about the licensing of each +file, are recorded in the LICENSE file. + +Files covered by a license with an assigned SPDX License Identifier +include SPDX-License-Identifier tags to enable automated processing of +license information. See https://spdx.org/licenses/ for more information. + +For any copyright range specified by files in this package as YYYY-ZZZZ, +the range specifies every single year in that closed interval. diff --git a/TODO b/TODO new file mode 100644 index 000000000000..876c5196a1bf --- /dev/null +++ b/TODO @@ -0,0 +1,101 @@ + pam-krb5 To-Do List + +PAM API: + + * Support PAM_CHANGE_EXPIRED_AUTHTOK properly in pam_chauthtok. This + will require prompting for the current password (if it's not already + available in the PAM data) and trying a regular authentication first to + see if the account is expired. + + * Tighter verification that all of our flags are valid might be a good + idea. + + * For informational messages followed by a prompt, find a way to combine + these into one PAM conversation call for better GUI presentation + behavior. + +Functionality: + + * Change the authentication flow so that both Heimdal and MIT use the + same logic for attempting PKINIT first and then falling back to + password. This will fix failure to store passwords in the PAM data + with try_pkinit and MIT Kerberos on password fallback and will allow + implementation of use_pkinit for MIT. Based on discussion with MIT + Kerberos upstream, the best approach is probably to configure a custom + prompter that refuses to reply to any prompt. + + * Add a daemon that can be used to verify TGTs that can be used when + pam-krb5 is run as a non-root user and hence doesn't have access to the + system keytab. Jeff Hutzelman has a daemon and protocol for doing this + developed for a different PAM authentication module, and it would be + good to stay consistent with that protocol if possible. (Debian + Bug#399001) + + * The alt_auth_map parsing to find realms doesn't take into account + escaped @-signs and doesn't do proper principal parsing. + + * Fix password expiration handling for the search_k5login and + alt_auth_map cases. Right now, we may return expired password errors + that would trigger password expiration handling, which probably isn't + correct. + + * Support authentication from a keytab. + + * Support disabling of user canonicalization so that the PAM user is + retained even if the module did an aname to lname mapping. + + * Use set_out_ccache to write the resulting ticket cache, if it is + available. This ensures the correct flags are set in the ticket cache. + This poses some challenges due to the two-step ticket cache mechanism + currently used. Perhaps there's a cache copying API? + + * Use krb5_chpw_message to parse password change messages from Active + Directory. + + * Consider exposing the Kerberos principal in the password prompt for a + password change. (Debian Bug#667928) + +Code Cleanup: + + * The PKINIT code for Heimdal involves too many #ifdefs right now for my + taste. Find a way to restructure it to only wrap the main PKINIT + function for Heimdal. + + * The current handling of error return codes is a mess. We need to find + a way to return a rich set of error codes from the underlying functions + and then map error codes appropriately in the interface functions. + Helpful for this would be improved documentation of what error codes + are permitted and where. + + * Tracking when to free the Kerberos context and other things stored in + the PAM context is currently too complicated. It should be possible to + simplify it with a reference counting scheme. + +Documentation: + + * Document PKINIT configuration with MIT in krb5.conf. It looks like the + library supports configuration in [realms] with similar names to the + PAM module configuration. + +Portability: + + * If pam_modutil_getpwnam is not available but getpwnam_r is, roll our + own using getpwnam_r. + +Logging: + + * Log the information that the Kerberos library asks us to display, or at + least the info and error messages. + + * Log unknown PAM flags on module entry. Currently, only the symbolic + flags we know about will be logged. + +Test suite: + + * Ensure that the test suite covers all possible PAM options. + + * Figure out why the pin-mit script for module/pkinit prompts twice and + check if it's a bug in the module. + + * Find a way of testing the PKINIT identity selection for MIT Kerberos + with use_pkinit enabled. diff --git a/bootstrap b/bootstrap new file mode 100755 index 000000000000..948aa1b9f02e --- /dev/null +++ b/bootstrap @@ -0,0 +1,13 @@ +#!/bin/sh +# +# Run this shell script to bootstrap as necessary after a fresh checkout. + +set -e + +autoreconf -i --force +rm -rf autom4te.cache + +# Generate manual pages. +version=`grep '^pam-krb5' NEWS | head -1 | cut -d' ' -f2` +pod2man --release="$version" --center=pam-krb5 -s 5 docs/pam_krb5.pod \ + >docs/pam_krb5.5 diff --git a/ci/README.md b/ci/README.md new file mode 100644 index 000000000000..fedd0d57fd08 --- /dev/null +++ b/ci/README.md @@ -0,0 +1,13 @@ +# Continuous Integration + +The files in this directory are used for continuous integration testing. +`ci/install` installs the prerequisite packages (run as root on a Debian +derivative), and `ci/test` runs the tests. + +Most tests will be skipped without a Kerberos configuration. The scripts +`ci/kdc-setup-heimdal` and `ci/kdc-setup-mit` will (when run as root on a +Debian derivative) set up a Heimdal or MIT Kerberos KDC, respectively, and +generate the files required to run the complete test suite. + +Tests are run automatically via GitHub Actions workflows using these +scripts and the configuration in the `.github/workflows` directory. diff --git a/ci/files/heimdal/heimdal-kdc b/ci/files/heimdal/heimdal-kdc new file mode 100644 index 000000000000..d7814631746d --- /dev/null +++ b/ci/files/heimdal/heimdal-kdc @@ -0,0 +1,9 @@ +# Heimdal KDC init script setup. -*- sh -*- + +# KDC configuration. +KDC_ENABLED=yes +KDC_PARAMS='--config-file=/etc/heimdal-kdc/kdc.conf' + +# kpasswdd configuration. +KPASSWDD_ENABLED=yes +KPASSWDD_PARAMS='-r HEIMDAL.TEST' diff --git a/ci/files/heimdal/kadmind.acl b/ci/files/heimdal/kadmind.acl new file mode 100644 index 000000000000..ae74ad5598ad --- /dev/null +++ b/ci/files/heimdal/kadmind.acl @@ -0,0 +1 @@ +test/admin@HEIMDAL.TEST all testuser@HEIMDAL.TEST diff --git a/ci/files/heimdal/kdc.conf b/ci/files/heimdal/kdc.conf new file mode 100644 index 000000000000..29ac52ebb947 --- /dev/null +++ b/ci/files/heimdal/kdc.conf @@ -0,0 +1,30 @@ +# Heimdal KDC configuration. -*- conf -*- + +[kadmin] + default_keys = aes256-cts-hmac-sha1-96:pw-salt + +[kdc] + acl_file = /etc/heimdal-kdc/kadmind.acl + check-ticket-addresses = false + logging = SYSLOG:NOTICE + ports = 88 + + # PKINIT configuration. + enable-pkinit = yes + pkinit_identity = FILE:/etc/heimdal-kdc/kdc.pem + pkinit_anchors = FILE:/etc/heimdal-kdc/ca/ca.pem + pkinit_mappings_file = /etc/heimdal-kdc/pki-mapping + pkinit_allow_proxy_certificate = no + pkinit_principal_in_certificate = no + +[libdefaults] + default_realm = HEIMDAL.TEST + dns_lookup_kdc = false + dns_lookup_realm = false + +[realms] + HEIMDAL.TEST.EYRIE.ORG = { + kdc = 127.0.0.1 + master_kdc = 127.0.0.1 + admin_server = 127.0.0.1 + } diff --git a/ci/files/heimdal/krb5.conf b/ci/files/heimdal/krb5.conf new file mode 100644 index 000000000000..a2b22c2d54cd --- /dev/null +++ b/ci/files/heimdal/krb5.conf @@ -0,0 +1,19 @@ +[libdefaults] + default_realm = HEIMDAL.TEST + dns_lookup_kdc = false + dns_lookup_realm = false + rdns = false + renew_lifetime = 7d + ticket_lifetime = 25h + +[realms] + HEIMDAL.TEST = { + kdc = 127.0.0.1 + master_kdc = 127.0.0.1 + admin_server = 127.0.0.1 + pkinit_anchors = FILE:/etc/heimdal-kdc/ca/ca.pem + } + +[logging] + kdc = SYSLOG:NOTICE + default = SYSLOG:NOTICE diff --git a/ci/files/heimdal/pki-mapping b/ci/files/heimdal/pki-mapping new file mode 100644 index 000000000000..76dd6b87edb6 --- /dev/null +++ b/ci/files/heimdal/pki-mapping @@ -0,0 +1 @@ +testuser@HEIMDAL.TEST:UID=testuser,DC=HEIMDAL,DC=TEST diff --git a/ci/files/mit/extensions.client b/ci/files/mit/extensions.client new file mode 100644 index 000000000000..5a1bbc29bdec --- /dev/null +++ b/ci/files/mit/extensions.client @@ -0,0 +1,19 @@ +[client_cert] +basicConstraints=CA:FALSE +keyUsage=digitalSignature,keyEncipherment,keyAgreement +extendedKeyUsage=1.3.6.1.5.2.3.4 +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer +issuerAltName=issuer:copy +subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:princ_name + +[princ_name] +realm=EXP:0,GeneralString:${ENV::REALM} +principal_name=EXP:1,SEQUENCE:principal_seq + +[principal_seq] +name_type=EXP:0,INTEGER:1 +name_string=EXP:1,SEQUENCE:principals + +[principals] +princ1=GeneralString:${ENV::CLIENT} diff --git a/ci/files/mit/extensions.kdc b/ci/files/mit/extensions.kdc new file mode 100644 index 000000000000..cbff73bef1ed --- /dev/null +++ b/ci/files/mit/extensions.kdc @@ -0,0 +1,20 @@ +[kdc_cert] +basicConstraints=CA:FALSE +keyUsage=nonRepudiation,digitalSignature,keyEncipherment,keyAgreement +extendedKeyUsage=1.3.6.1.5.2.3.5 +subjectKeyIdentifier=hash +authorityKeyIdentifier=keyid,issuer +issuerAltName=issuer:copy +subjectAltName=otherName:1.3.6.1.5.2.2;SEQUENCE:kdc_princ_name + +[kdc_princ_name] +realm=EXP:0,GeneralString:${ENV::REALM} +principal_name=EXP:1,SEQUENCE:kdc_principal_seq + +[kdc_principal_seq] +name_type=EXP:0,INTEGER:1 +name_string=EXP:1,SEQUENCE:kdc_principals + +[kdc_principals] +princ1=GeneralString:krbtgt +princ2=GeneralString:${ENV::REALM} diff --git a/ci/files/mit/kadm5.acl b/ci/files/mit/kadm5.acl new file mode 100644 index 000000000000..652bbecb84b2 --- /dev/null +++ b/ci/files/mit/kadm5.acl @@ -0,0 +1 @@ +test/admin@MIT.TEST mci testuser@MIT.TEST diff --git a/ci/files/mit/kdc.conf b/ci/files/mit/kdc.conf new file mode 100644 index 000000000000..7bf4e6a06e95 --- /dev/null +++ b/ci/files/mit/kdc.conf @@ -0,0 +1,19 @@ +[kdcdefaults] + kdc_ports = 88 + kdc_tcp_ports = 88 + restrict_anonymous_to_tgt = true + +[realms] + MIT.TEST = { + database_name = /var/lib/krb5kdc/principal + admin_keytab = /var/lib/krb5kdc/kadm5.keytab + acl_file = /etc/krb5kdc/kadm5.acl + key_stash_file = /var/lib/krb5kdc/stash + max_life = 1d 1h 0m 0s + max_renewable_life = 7d 0h 0m 0s + master_key_type = aes256-cts + supported_enctypes = aes256-cts:normal + default_principal_flags = +preauth + pkinit_identity = FILE:/var/lib/krb5kdc/kdc.pem,/var/lib/krb5kdc/kdckey.pem + pkinit_anchors = FILE:/etc/krb5kdc/cacert.pem + } diff --git a/ci/files/mit/krb5.conf b/ci/files/mit/krb5.conf new file mode 100644 index 000000000000..9b0d5ab9dbdf --- /dev/null +++ b/ci/files/mit/krb5.conf @@ -0,0 +1,19 @@ +[libdefaults] + default_realm = MIT.TEST + dns_lookup_kdc = false + dns_lookup_realm = false + rdns = false + renew_lifetime = 7d + ticket_lifetime = 25h + +[realms] + MIT.TEST = { + kdc = 127.0.0.1 + master_kdc = 127.0.0.1 + admin_server = 127.0.0.1 + pkinit_anchors = FILE:/etc/krb5kdc/cacert.pem + } + +[logging] + kdc = SYSLOG:NOTICE + default = SYSLOG:NOTICE diff --git a/ci/install b/ci/install new file mode 100755 index 000000000000..b53ac2957546 --- /dev/null +++ b/ci/install @@ -0,0 +1,18 @@ +#!/bin/sh +# +# Install packages for integration tests. +# +# This script is normally run via sudo in a test container or VM, such as via +# GitHub Actions. +# +# Copyright 2015-2021 Russ Allbery +# +# SPDX-License-Identifier: MIT + +set -eux + +# Install distribution packages. +apt-get update -qq +apt-get install aspell autoconf automake cppcheck heimdal-multidev \ + krb5-config libkrb5-dev libpam0g-dev libtest-pod-perl \ + libtest-spelling-perl libtool perl valgrind diff --git a/ci/kdc-setup-heimdal b/ci/kdc-setup-heimdal new file mode 100755 index 000000000000..9d15b1a4a6de --- /dev/null +++ b/ci/kdc-setup-heimdal @@ -0,0 +1,105 @@ +#!/bin/sh +# +# Build a Kerberos test realm for Heimdal. +# +# This script automates the process of setting up a Kerberos test realm from +# scratch suitable for testing pam-krb5. It is primarily intended to be run +# from inside CI in a VM or container from the top of the pam-krb5 source +# tree, and must be run as root. It expects to be operating on the Debian +# Heimdal package. +# +# Copyright 2014, 2020 Russ Allbery +# +# SPDX-License-Identifier: MIT + +set -eux + +# Install the KDC. +apt-get install heimdal-kdc + +# Install its configuration files. +cp ci/files/heimdal/heimdal-kdc /etc/default/heimdal-kdc +cp ci/files/heimdal/kadmind.acl /etc/heimdal-kdc/kadmind.acl +cp ci/files/heimdal/kdc.conf /etc/heimdal-kdc/kdc.conf +cp ci/files/heimdal/krb5.conf /etc/krb5.conf +cp ci/files/heimdal/pki-mapping /etc/heimdal-kdc/pki-mapping + +# Some versions of heimdal-kdc require this. +ln -s /etc/heimdal-kdc/kadmind.acl /var/lib/heimdal-kdc/kadmind.acl + +# Add domain-realm mappings for the local host, since otherwise Heimdal and +# MIT Kerberos may attempt to discover the realm of the local domain, and the +# DNS server for GitHub Actions has a habit of just not responding and causing +# the test to hang. +cat <>/etc/krb5.conf +[domain_realm] + $(hostname -f) = HEIMDAL.TEST +EOF +cat <>/etc/heimdal-kdc/kdc.conf +[domain_realm] + $(hostname -f) = HEIMDAL.TEST +EOF + +# Create the basic KDC. +kstash --random-key +kadmin -l init --realm-max-ticket-life='1 day 1 hour' \ + --realm-max-renewable-life='1 week' HEIMDAL.TEST + +# Set default principal policies. +kadmin -l modify --attributes=requires-pre-auth,disallow-svr \ + default@HEIMDAL.TEST + +# Create and store the keytabs. +kadmin -l add -r --use-defaults --attributes=requires-pre-auth \ + test/admin@HEIMDAL.TEST +kadmin -l ext_keytab -k tests/config/admin-keytab test/admin@HEIMDAL.TEST +kadmin -l add -r --use-defaults --attributes=requires-pre-auth \ + test/keytab@HEIMDAL.TEST +kadmin -l ext_keytab -k tests/config/keytab test/keytab@HEIMDAL.TEST + +# Create a user principal with a known password. +password="iceedKaicVevjunwiwyd" +kadmin -l add --use-defaults --password="$password" testuser@HEIMDAL.TEST +echo 'testuser@HEIMDAL.TEST' >tests/config/password +echo "$password" >>tests/config/password + +# Create the root CA for PKINIT. +mkdir -p /etc/heimdal-kdc/ca +hxtool issue-certificate --self-signed --issue-ca --generate-key=rsa \ + --subject=CN=CA,DC=HEIMDAL,DC=TEST --lifetime=10years \ + --certificate=FILE:/etc/heimdal-kdc/ca/ca.pem +chmod 644 /etc/heimdal-kdc/ca/ca.pem + +# Create the certificate for the Heimdal Kerberos KDC. +hxtool issue-certificate --ca-certificate=FILE:/etc/heimdal-kdc/ca/ca.pem \ + --generate-key=rsa --type=pkinit-kdc \ + --pk-init-principal=krbtgt/HEIMDAL.TEST@HEIMDAL.TEST \ + --subject=uid=kdc,DC=HEIMDAL,DC=TEST \ + --certificate=FILE:/etc/heimdal-kdc/kdc.pem +chmod 644 /etc/heimdal-kdc/kdc.pem + +# Create the certificate for the Heimdal client. +hxtool issue-certificate --ca-certificate=FILE:/etc/heimdal-kdc/ca/ca.pem \ + --generate-key=rsa --type=pkinit-client \ + --pk-init-principal=testuser@HEIMDAL.TEST \ + --subject=UID=testuser,DC=HEIMDAL,DC=TEST \ + --certificate=FILE:tests/config/pkinit-cert +echo 'testuser@HEIMDAL.TEST' >tests/config/pkinit-principal + +# Fix permissions on all the newly-created files. +chmod 644 tests/config/* + +# Restart the Heimdal KDC and services. +systemctl stop heimdal-kdc +systemctl start heimdal-kdc + +# Ensure that the KDC is running. +for n in $(seq 1 5); do + if echo "$password" \ + | kinit --password-file=STDIN testuser@HEIMDAL.TEST; then + break + fi + sleep 1 +done +klist +kdestroy diff --git a/ci/kdc-setup-mit b/ci/kdc-setup-mit new file mode 100755 index 000000000000..0b3dfb60b64b --- /dev/null +++ b/ci/kdc-setup-mit @@ -0,0 +1,102 @@ +#!/bin/sh +# +# Build a Kerberos test realm for MIT Kerberos +# +# This script automates the process of setting up a Kerberos test realm from +# scratch suitable for testing pam-krb5. It is primarily intended to be run +# from inside CI in a VM or container from the top of the pam-krb5 source +# tree, and must be run as root. It expects to be operating on the Debian +# MIT Kerberos package. +# +# Copyright 2014, 2020 Russ Allbery +# +# SPDX-License-Identifier: MIT + +set -eux + +# Install the KDC and the OpenSSL command line tool. +apt-get install krb5-admin-server krb5-kdc krb5-pkinit openssl + +# Install its configuration files. +cp ci/files/mit/extensions.client /etc/krb5kdc/extensions.client +cp ci/files/mit/extensions.kdc /etc/krb5kdc/extensions.kdc +cp ci/files/mit/kadm5.acl /etc/krb5kdc/kadm5.acl +cp ci/files/mit/kdc.conf /etc/krb5kdc/kdc.conf +cp ci/files/mit/krb5.conf /etc/krb5.conf + +# Add domain-realm mappings for the local host, since otherwise Heimdal and +# MIT Kerberos may attempt to discover the realm of the local domain, and the +# DNS server for GitHub Actions has a habit of just not responding and causing +# the test to hang. +cat <>/etc/krb5.conf +[domain_realm] + $(hostname -f) = MIT.TEST +EOF + +# Create the basic KDC. +kdb5_util create -s -P 'this is a test master database password' + +# Create and store the keytabs. +kadmin.local -q 'add_principal +requires_preauth -randkey test/admin@MIT.TEST' +kadmin.local -q 'ktadd -k tests/config/admin-keytab test/admin@MIT.TEST' +kadmin.local -q 'add_principal +requires_preauth -randkey test/keytab@MIT.TEST' +kadmin.local -q 'ktadd -k tests/config/keytab test/keytab@MIT.TEST' + +# Enable anonymous PKINIT. +kadmin.local -q 'addprinc -randkey WELLKNOWN/ANONYMOUS' + +# Create a user principal with a known password. +password="iceedKaicVevjunwiwyd" +kadmin.local -q \ + "add_principal +requires_preauth -pw $password testuser@MIT.TEST" +echo 'testuser@MIT.TEST' >tests/config/password +echo "$password" >>tests/config/password + +# Create the root CA for PKINIT. +openssl genrsa -out /etc/krb5kdc/cakey.pem 2048 +openssl req -key /etc/krb5kdc/cakey.pem -new -x509 \ + -out /etc/krb5kdc/cacert.pem -subj "/CN=MIT.TEST CA" -days 3650 +chmod 755 /etc/krb5kdc +chmod 644 /etc/krb5kdc/cacert.pem + +# Create the certificate for the MIT Kerberos KDC. +openssl genrsa -out /var/lib/krb5kdc/kdckey.pem 2048 +openssl req -new -out /var/lib/krb5kdc/kdc.req \ + -key /var/lib/krb5kdc/kdckey.pem -subj "/CN=MIT.TEST" +REALM=MIT.TEST openssl x509 -req -in /var/lib/krb5kdc/kdc.req \ + -CAkey /etc/krb5kdc/cakey.pem -CA /etc/krb5kdc/cacert.pem \ + -out /var/lib/krb5kdc/kdc.pem -days 365 \ + -extfile /etc/krb5kdc/extensions.kdc -extensions kdc_cert \ + -CAcreateserial +rm /var/lib/krb5kdc/kdc.req + +# Create the certificate for the MIT Kerberos client. +openssl genrsa -out clientkey.pem 2048 +openssl req -new -key clientkey.pem -out client.req \ + -subj "/CN=testuser@MIT.TEST" +REALM="MIT.TEST" CLIENT="testuser" openssl x509 \ + -CAkey /etc/krb5kdc/cakey.pem -CA /etc/krb5kdc/cacert.pem -req \ + -in client.req -extensions client_cert \ + -extfile /etc/krb5kdc/extensions.client -days 365 -out client.pem +cat client.pem clientkey.pem >tests/config/pkinit-cert +rm clientkey.pem client.pem client.req +echo 'testuser@MIT.TEST' >tests/config/pkinit-principal + +# Fix permissions on all the newly-created files. +chmod 644 tests/config/* + +# Restart the MIT Kerberos KDC and services. +systemctl stop krb5-kdc krb5-admin-server +systemctl start krb5-kdc krb5-admin-server + +# Ensure that the KDC is running. +for n in $(seq 1 5); do + if echo "$password" | kinit testuser@MIT.TEST; then + break + fi + sleep 1 +done +klist +kdestroy +kinit -n @MIT.TEST +kinit -X X509_user_identity=FILE:tests/config/pkinit-cert testuser@MIT.TEST diff --git a/ci/test b/ci/test new file mode 100755 index 000000000000..b7844bdd75fe --- /dev/null +++ b/ci/test @@ -0,0 +1,44 @@ +#!/bin/sh +# +# Run tests for continuous integration. +# +# This script is normally run in a test container or VM, such as via GitHub +# Actions. +# +# Copyright 2015-2021 Russ Allbery +# +# SPDX-License-Identifier: MIT + +set -eux + +# Normally, KERBEROS is set based on the CI matrix, but provide a default in +# case someone runs this test by hand. +KERBEROS="${KERBEROS:-mit}" + +# Generate Autotools files. +./bootstrap + +# Build everything with Clang first, with warnings enabled. +if [ "$KERBEROS" = 'heimdal' ]; then + ./configure CC=clang PATH_KRB5_CONFIG=/usr/bin/krb5-config.heimdal +else + ./configure CC=clang +fi +make warnings + +# Then rebuild everything with GCC with warnings enabled. +make distclean +if [ "$KERBEROS" = 'heimdal' ]; then + ./configure CC=gcc PATH_KRB5_CONFIG=/usr/bin/krb5-config.heimdal +else + ./configure CC=gcc +fi +make warnings + +# Run the tests with valgrind. +make check-valgrind + +# Run additional style tests, but only in the MIT build. +if [ "$KERBEROS" = "mit" ]; then + make check-cppcheck +fi diff --git a/configure.ac b/configure.ac new file mode 100644 index 000000000000..eddc6fd46559 --- /dev/null +++ b/configure.ac @@ -0,0 +1,145 @@ +dnl Autoconf configuration for pam-krb5. +dnl +dnl Written by Russ Allbery +dnl Copyright 2005-2009, 2014, 2017, 2020-2021 Russ Allbery +dnl Copyright 2009-2013 +dnl The Board of Trustees of the Leland Stanford Junior University +dnl Copyright 2005 Andres Salomon +dnl Copyright 1999-2000 Frank Cusack +dnl +dnl SPDX-License-Identifier: BSD-3-clause or GPL-1+ + +AC_PREREQ([2.64]) +AC_INIT([pam-krb5], [4.11], [eagle@eyrie.org]) +AC_CONFIG_AUX_DIR([build-aux]) +AC_CONFIG_LIBOBJ_DIR([portable]) +AC_CONFIG_MACRO_DIR([m4]) +AM_INIT_AUTOMAKE([1.11 check-news dist-xz foreign silent-rules subdir-objects + -Wall -Werror]) +AM_MAINTAINER_MODE + +dnl Detect unexpanded macros. +m4_pattern_forbid([^PKG_]) +m4_pattern_forbid([^_?RRA_]) + +AC_PROG_CC +AC_USE_SYSTEM_EXTENSIONS +RRA_PROG_CC_WARNINGS_FLAGS +AC_SYS_LARGEFILE +AM_PROG_CC_C_O +m4_ifdef([AM_PROG_AR], [AM_PROG_AR]) +AC_PROG_INSTALL +LT_INIT([disable-static]) +AC_CANONICAL_HOST +RRA_LD_VERSION_SCRIPT + +dnl Only used for the test suite. +AC_ARG_VAR([PATH_OPENSSL], [Path to openssl for the test suite]) +AC_PATH_PROG([PATH_OPENSSL], [openssl]) +AS_IF([test x"$PATH_OPENSSL" != x], + [AC_DEFINE_UNQUOTED([PATH_OPENSSL], ["$PATH_OPENSSL"], + [Define to the full path to openssl for some tests.])]) +AC_ARG_VAR([PATH_VALGRIND], [Path to valgrind for the test suite]) +AC_PATH_PROG([PATH_VALGRIND], [valgrind]) + +dnl Probe for the functionality of the PAM libraries and their include file +dnl naming. Mac OS X puts them in pam/* instead of security/*. +AC_SEARCH_LIBS([pam_set_data], [pam]) +AC_CHECK_FUNCS([pam_getenv pam_getenvlist pam_modutil_getpwnam]) +AC_REPLACE_FUNCS([pam_syslog pam_vsyslog]) +AC_CHECK_HEADERS([security/pam_modutil.h], [], + [AC_CHECK_HEADERS([pam/pam_modutil.h])]) +AC_CHECK_HEADERS([security/pam_appl.h], [], + [AC_CHECK_HEADERS([pam/pam_appl.h], [], + [AC_MSG_ERROR([No PAM header files found])])]) +AC_CHECK_HEADERS([security/pam_ext.h], [], + [AC_CHECK_HEADERS([pam/pam_ext.h])]) +RRA_HEADER_PAM_CONST +RRA_HEADER_PAM_STRERROR_CONST +AC_DEFINE([MODULE_NAME], ["pam_krb5"], + [The name of the PAM module, used by the pam_vsyslog replacement.]) + +dnl Probe for the location and functionality of the Kerberos libraries. +RRA_LIB_KRB5 +RRA_LIB_KRB5_SWITCH +AC_CHECK_HEADERS([hx509_err.h]) +AC_CHECK_MEMBER([krb5_creds.session], + [AC_DEFINE([HAVE_KRB5_HEIMDAL], [1], + [Define if your Kerberos implementation is Heimdal.])], + [AC_DEFINE([HAVE_KRB5_MIT], [1], + [Define if your Kerberos implementation is MIT.])], + [RRA_INCLUDES_KRB5]) +AC_CHECK_TYPES([krb5_realm], [], [], [RRA_INCLUDES_KRB5]) +AC_CHECK_FUNCS([krb5_cc_get_full_name \ + krb5_data_free \ + krb5_free_default_realm \ + krb5_free_string \ + krb5_get_init_creds_opt_alloc \ + krb5_get_init_creds_opt_set_anonymous \ + krb5_get_init_creds_opt_set_change_password_prompt \ + krb5_get_init_creds_opt_set_default_flags \ + krb5_get_init_creds_opt_set_fast_ccache_name \ + krb5_get_init_creds_opt_set_out_ccache \ + krb5_get_init_creds_opt_set_pa \ + krb5_get_prompt_types \ + krb5_init_secure_context \ + krb5_principal_get_realm \ + krb5_principal_set_comp_string \ + krb5_set_password \ + krb5_set_trace_filename \ + krb5_verify_init_creds_opt_init \ + krb5_xfree]) +AC_CHECK_FUNCS([krb5_get_init_creds_opt_set_pkinit], + [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT_ARGS]) +AC_CHECK_FUNCS([krb5_get_init_creds_opt_free], + [RRA_FUNC_KRB5_GET_INIT_CREDS_OPT_FREE_ARGS]) +AC_CHECK_DECLS([krb5_kt_free_entry], [], [], [RRA_INCLUDES_KRB5]) +AC_CHECK_FUNCS([krb5_appdefault_string], [], + [AC_CHECK_FUNCS([krb5_get_profile]) + AC_CHECK_HEADERS([k5profile.h profile.h]) + AC_LIBOBJ([krb5-profile])]) +AC_LIBOBJ([krb5-extra]) +RRA_LIB_KRB5_RESTORE + +dnl The kadmin client libraries are only used for the test suite. +RRA_LIB_KADM5CLNT_OPTIONAL +RRA_LIB_KADM5CLNT_SWITCH +AC_CHECK_HEADERS([kadm5/kadm5_err.h]) +AC_CHECK_FUNCS([kadm5_init_krb5_context kadm5_init_with_skey_ctx]) +RRA_LIB_KADM5CLNT_RESTORE + +dnl Regex support is only used for the test suite. +AC_CHECK_HEADER([regex.h], [AC_CHECK_FUNCS([regcomp])]) + +dnl Other probes of the system libraries. +AC_HEADER_STDBOOL +AC_CHECK_HEADERS([strings.h sys/bittypes.h sys/select.h sys/time.h]) +AC_CHECK_DECLS([reallocarray]) +AC_TYPE_LONG_LONG_INT +AC_CHECK_TYPES([ssize_t], [], [], + [#include ]) +AC_CHECK_FUNCS([explicit_bzero]) +AC_REPLACE_FUNCS([asprintf issetugid mkstemp reallocarray strndup]) + +dnl Try to specify the binding so that any references within the PAM module +dnl are resolved to the functions in that module in preference to any external +dnl function. +dnl +dnl More platforms could be handled here. Contributions welcome. +AS_CASE([$host], + [*-hpux*], + [AS_IF([test x"$GCC" = x"yes"], + [AM_LDFLAGS="-Wl,-Bsymbolic $AM_LDFLAGS"], + [AM_LDFLAGS="-Wl,+vshlibunsats $AM_LDFLAGS"])], + + [*-linux*], + [AM_LDFLAGS="-Wl,-z,defs -Wl,-Bsymbolic $AM_LDFLAGS"], + + [*-solaris2*], + [AS_IF([test x"$GCC" = x"yes"], + [AM_LDFLAGS="-Wl,-Bsymbolic $AM_LDFLAGS"], + [AM_LDFLAGS="-Wl,-xldscope=symbolic $AM_LDFLAGS"])]) + +AC_CONFIG_HEADERS([config.h]) +AC_CONFIG_FILES([Makefile]) +AC_OUTPUT diff --git a/docs/docknot.yaml b/docs/docknot.yaml new file mode 100644 index 000000000000..67e19f88d50a --- /dev/null +++ b/docs/docknot.yaml @@ -0,0 +1,551 @@ +# Package metadata for pam-krb5. +# +# This file contains configuration for DocKnot used to generate +# documentation files (like README.md) and web pages. Other documentation +# in this package is generated automatically from these files as part of +# the release process. For more information, see DocKnot's documentation. +# +# DocKnot is available from . +# +# Copyright 2017, 2020-2021 Russ Allbery +# +# SPDX-License-Identifier: BSD-3-clause or GPL-1+ + +format: v1 + +name: pam-krb5 +maintainer: Russ Allbery +version: '4.11' +synopsis: PAM module for Kerberos authentication + +license: + name: BSD-3-clause-or-GPL-1+ +copyrights: + - holder: Russ Allbery + years: 2005-2010, 2014-2015, 2017, 2020-2021 + - holder: The Board of Trustees of the Leland Stanford Junior University + years: 2009-2011 + - holder: Andres Salomon + years: '2005' + - holder: Frank Cusack + years: 1999-2000 + +build: + autoconf: '2.64' + automake: '1.11' + autotools: true + kerberos: true + manpages: true + middle: | + The module will be installed in `/usr/local/lib/security` by default, but + expect to have to override this using `--libdir`. The correct + installation path for PAM modules varies considerably between systems. + The module will always be installed in a subdirectory named `security` + under the specified value of `--libdir`. On Red Hat Linux, for example, + `--libdir=/usr/lib64` is appropriate to install the module into the system + PAM directory. On Debian's amd64 architecture, + `--libdir=/usr/lib/x86_64-linux-gnu` would be correct. + reduced_depends: true + type: Autoconf + valgrind: true +distribution: + packaging: + debian: + package: libpam-krb5 + summary: | + Debian packages are available from Debian in Debian 4.0 (etch) and + later releases as libpam-krb5 and libpam-heimdal. The former packages + are built against the MIT Kerberos libraries and the latter against + the Heimdal libraries. + section: kerberos + tarname: pam-krb5 + version: pam-krb5 +support: + email: eagle@eyrie.org + github: rra/pam-krb5 + web: https://www.eyrie.org/~eagle/software/pam-krb5/ +vcs: + browse: https://git.eyrie.org/?p=kerberos/pam-krb5.git + github: rra/pam-krb5 + openhub: https://www.openhub.net/p/pamkrb5 + status: + workflow: build + type: Git + url: https://git.eyrie.org/git/kerberos/pam-krb5.git + +quote: + author: Joyce McGreevy + date: 2003-11-17 + text: | + "You're always going to have some people who can't appreciate the thrill + of a tepid change for the somewhat better," explained one source. + title: '"Look, ma, no hands!"' + work: Salon +advisories: + - date: 2020-03-30 + threshold: '4.9' + versions: 4.8 and earlier + - date: 2009-02-11 + threshold: '3.13' + versions: 3.12 and earlier +docs: + user: + - name: pam-krb5 + title: Manual page + +blurb: | + pam-krb5 is a Kerberos PAM module for either MIT Kerberos or Heimdal. It + supports ticket refreshing by screen savers, configurable authorization + handling, authentication of non-local accounts for network services, + password changing, and password expiration, as well as all the standard + expected PAM features. It works correctly with OpenSSH, even with + ChallengeResponseAuthentication and PrivilegeSeparation enabled, and + supports extensive configuration either by PAM options or in krb5.conf or + both. PKINIT is supported with recent versions of both MIT Kerberos and + Heimdal and FAST is supported with recent MIT Kerberos. + +description: | + pam-krb5 provides a Kerberos PAM module that supports authentication, user + ticket cache handling, simple authorization (via .k5login or checking + Kerberos principals against local usernames), and password changing. It can + be configured through either options in the PAM configuration itself or + through entries in the system krb5.conf file, and it tries to work around + PAM implementation flaws in commonly-used PAM-enabled applications such as + OpenSSH and xdm. It supports both PKINIT and FAST to the extent that the + underlying Kerberos libraries support these features. + + This is not the Kerberos PAM module maintained on Sourceforge and used on + Red Hat systems. It is an independent implementation that, if it ever + shared any common code, diverged long ago. It supports some features that + the Sourceforge module does not (particularly around authorization), and + does not support some options (particularly ones not directly related to + Kerberos) that it does. This module will never support Kerberos v4 or AFS. + For an AFS session module that works with this module (or any other Kerberos + PAM module), see + [pam-afs-session](https://www.eyrie.org/~eagle/software/pam-afs-session/). + + If there are other options besides AFS and Kerberos v4 support from the + Sourceforge PAM module that you're missing in this module, please let me + know. + +requirements: | + Either MIT Kerberos (or Kerberos implementations based on it) or Heimdal are + supported. MIT Keberos 1.3 or later may be required; this module has not + been tested with earlier versions. + + For PKINIT support, Heimdal 0.8rc1 or later or MIT Kerberos 1.6.3 or later + are required. Earlier MIT Kerberos 1.6 releases have a bug in their + handling of PKINIT options. MIT Kerberos 1.12 or later is required to use + the use_pkinit PAM option. + + For FAST (Flexible Authentication Secure Tunneling) support, MIT Kerberos + 1.7 or higher is required. For anonymous FAST support, anonymous + authentication (generally anonymous PKINIT) support is required in both the + Kerberos libraries and in the local KDC. + + This module should work on Linux and build with gcc or clang. It may still + work on Solaris and build with the Sun C compiler, but I have only tested it + on Linux recently. There is beta-quality support for the AIX NAS Kerberos + implementation that has not been tested in years. Other PAM implementations + will probably require some porting, although untested build system support + is present for FreeBSD, Mac OS X, and HP-UX. I personally can only test on + Linux and rely on others to report problems on other operating systems. + + Old versions of OpenSSH are known to call `pam_authenticate` followed by + `pam_setcred(PAM_REINITIALIZE_CRED)` without first calling + `pam_open_session`, thereby requesting that an existing ticket cache be + renewed (similar to what a screensaver would want) rather than requesting a + new ticket cache be created. Since this behavior is indistinguishable at + the PAM level from a screensaver, pam-krb5 when used with these old versions + of OpenSSH will refresh the ticket cache of the OpenSSH daemon rather than + setting up a new ticket cache for the user. The resulting ticket cache will + have the correct permissions (this is not a security concern), but will not + be named correctly or referenced in the user's environment and will be + overwritten by the next user login. The best solution to this problem is to + upgrade OpenSSH. I'm not sure exactly when this problem was fixed, but at + the very least OpenSSH 4.3 and later do not exhibit it. + +test: + lancaster: true + prefix: | + pam-krb5 comes with a comprehensive test suite, but it requires some + configuration in order to test anything other than low-level utility + functions. For the full test suite, you will need to have a running KDC + in which you can create two test accounts, one with admin access to the + other. Using a test KDC environment, if you have one, is recommended. + + Follow the instructions in `tests/config/README` to configure the test + suite. + + Now, you can run the test suite with: + suffix: | + The default libkadm5clnt library on the system must match the + implementation of your KDC for the module/expired test to work, since the + two kadmin protocols are not compatible. If you use the MIT library + against a Heimdal server, the test will be skipped; if you use the Heimdal + library against an MIT server, the test suite may hang. + + Several `module/expired` tests are expected to fail with Heimdal 1.5 due + to a bug in Heimdal with reauthenticating immediately after a + library-mediated password change of an expired password. This is fixed in + later releases of Heimdal. + + To run the full test suite, Perl 5.10 or later is required. The following + additional Perl modules will be used if present: + + * Test::Pod + * Test::Spelling + + All are available on CPAN. Those tests will be skipped if the modules are + not available. + +sections: + - title: Configuring + body: | + Just installing the module does not enable it or change anything about + your system authentication configuration. To use the module for all + system authentication on Debian systems, put something like: + + ``` + auth sufficient pam_krb5.so minimum_uid=1000 + auth required pam_unix.so try_first_pass nullok_secure + ``` + + in `/etc/pam.d/common-auth`, something like: + + ``` + session optional pam_krb5.so minimum_uid=1000 + session required pam_unix.so + ``` + + in `/etc/pam.d/common-session`, and something like: + + ``` + account required pam_krb5.so minimum_uid=1000 + account required pam_unix.so + ``` + + in `/etc/pam.d/common-account`. The `minimum_uid` setting tells the PAM + module to pass on any users with a UID lower than 1000, thereby + bypassing Kerberos authentication for the root account and any system + accounts. You normally want to do this since otherwise, if the network + is down, the Kerberos authentication can time out and make it difficult + to log in as root and fix matters. This also avoids problems with + Kerberos principals that happen to match system accounts accidentally + getting access to those accounts. + + Be sure to include the module in the session group as well as the auth + group. Without the session entry, the user's ticket cache will not be + created properly for ssh logins (among possibly others). + + If your users should normally all use Kerberos passwords exclusively, + putting something like: + + ``` + password sufficient pam_krb5.so minimum_uid=1000 + password required pam_unix.so try_first_pass obscure md5 + ``` + + in `/etc/pam.d/common-password` will change users' passwords in Kerberos + by default and then only fall back on Unix if that doesn't work. (You + can make this tighter by using the more complex new-style PAM + configuration.) If you instead want to synchronize local and Kerberos + passwords and change them both at the same time, you can do something + like: + + ``` + password required pam_unix.so obscure sha512 + password required pam_krb5.so use_authtok minimum_uid=1000 + ``` + + If you have multiple environments that you want to synchronize and you + don't want password changes to continue if the Kerberos password change + fails, use the `clear_on_fail` option. For example: + + ``` + password required pam_krb5.so clear_on_fail minimum_uid=1000 + password required pam_unix.so use_authtok obscure sha512 + password required pam_smbpass.so use_authtok + ``` + + In this case, if `pam_krb5` cannot change the password (due to password + strength rules on the KDC, for example), it will clear the stored + password (because of the `clear_on_fail` option), and since `pam_unix` + and `pam_smbpass` are both configured with `use_authtok`, they will both + fail. `clear_on_fail` is not the default because it would interfere + with the more common pattern of falling back to local passwords if the + user doesn't exist in Kerberos. + + If you use a more complex configuration with the Linux PAM `[]` syntax + for the session and account groups, note that `pam_krb5` returns a + status of ignore, not success, if the user didn't log on with Kerberos. + You may need to handle that explicitly with `ignore=ignore` in your + action list. + + There are many, many other possibilities. See the Linux PAM + documentation for all the configuration options. + + On Red Hat systems, modify `/etc/pam.d/system-auth` instead, which + contains all of the configuration for the different stacks. + + You can also use pam-krb5 only for specific services. In that case, + modify the files in `/etc/pam.d` for that particular service to use + `pam_krb5.so` for authentication. For services that are using passwords + over TLS to authenticate users, you may want to use the `ignore_k5login` + and `no_ccache` options to the authenticate module. `.k5login` + authorization is only meaningful for local accounts and ticket caches + are usually (although not always) only useful for interactive sessions. + + Configuring the module for Solaris is both simpler and less flexible, + since Solaris (at least Solaris 8 and 9, which are the last versions of + Solaris with which this module was extensively tested) use a single + `/etc/pam.conf` file that contains configuration for all programs. For + console login on Solaris, try something like: + + ``` + login auth sufficient /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login auth required /usr/lib/security/pam_unix_auth.so.1 use_first_pass + login account required /usr/local/lib/security/pam_krb5.so minimum_uid=100 + login account required /usr/lib/security/pam_unix_account.so.1 + login session required /usr/local/lib/security/pam_krb5.so retain_after_close minimum_uid=100 + login session required /usr/lib/security/pam_unix_session.so.1 + ``` + + A similar configuration could be used for other services, such as ssh. + See the pam.conf(5) man page for more information. When using this + module with Solaris login (at least on Solaris 8 and 9), you will + probably also need to add `retain_after_close` to the PAM configuration + to avoid having the user's credentials deleted before they are logged + in. + + The Solaris Kerberos library reportedly does not support prompting for a + password change of an expired account during authentication. Supporting + password change for expired accounts on Solaris with native Kerberos may + therefore require setting the `defer_pwchange` or `force_pwchange` + option for selected login applications. See the description and + warnings about that option in the pam_krb5(5) man page. + + Some configuration options may be put in the `krb5.conf` file used by + your Kerberos libraries (usually `/etc/krb5.conf` or + `/usr/local/etc/krb5.conf`) instead or in addition to the PAM + configuration. See the man page for more details. + + The Kerberos library, via pam-krb5, will prompt the user to change their + password if their password is expired, but when using OpenSSH, this will + only work when `ChallengeResponseAuthentication` is enabled. Unless + this option is enabled, OpenSSH doesn't pass PAM messages to the user + and can only respond to a simple password prompt. + + If you are using MIT Kerberos, be aware that users whose passwords are + expired will not be prompted to change their password unless the KDC + configuration for your realm in `[realms]` in `krb5.conf` contains a + `master_kdc` setting or, if using DNS SRV records, you have a DNS entry + for `_kerberos-master` as well as `_kerberos`. + - title: Debugging + body: | + The first step when debugging any problems with this module is to add + `debug` to the PAM options for the module (either in the PAM + configuration or in `krb5.conf`). This will significantly increase the + logging from the module and should provide a trace of exactly what + failed and any available error information. + + Many Kerberos authentication problems are due to configuration issues in + `krb5.conf`. If pam-krb5 doesn't work, first check that `kinit` works + on the same system. That will test your basic Kerberos configuration. + If the system has a keytab file installed that's readable by the process + doing authentication via PAM, make sure that the keytab is current and + contains a key for `host/` where is the fully-qualified + hostname. pam-krb5 prevents KDC spoofing by checking the user's + credentials when possible, but this means that if a keytab is present it + must be correct or authentication will fail. You can check the keytab + with `klist -k` and `kinit -k`. + + Be sure that all libraries and modules, including PAM modules, loaded by + a program use the same Kerberos libraries. Sometimes programs that use + PAM, such as current versions of OpenSSH, also link against Kerberos + directly. If your sshd is linked against one set of Kerberos libraries + and pam-krb5 is linked against a different set of Kerberos libraries, + this will often cause problems (such as segmentation faults, bus errors, + assertions, or other strange behavior). Similar issues apply to the + com_err library or any other library used by both modules and shared + libraries and by the application that loads them. If your OS ships + Kerberos libraries, it's usually best if possible to build all Kerberos + software on the system against those libraries. + - title: Implementation Notes + body: | + The normal sequence of actions taken for a user login is: + + ``` + pam_authenticate + pam_setcred(PAM_ESTABLISH_CRED) + pam_open_session + pam_acct_mgmt + ``` + + and then at logout: + + ``` + pam_close_session + ``` + + followed by closing the open PAM session. The corresponding `pam_sm_*` + functions in this module are called when an application calls those + public interface functions. Not all applications call all of those + functions, or in particularly that order, although `pam_authenticate` is + always first and has to be. + + When `pam_authenticate` is called, pam-krb5 creates a temporary ticket + cache in `/tmp` and sets the PAM environment variable `PAM_KRB5CCNAME` + to point to it. This ticket cache will be automatically destroyed when + the PAM session is closed and is there only to pass the initial + credentials to the call to `pam_setcred`. The module would use a memory + cache, but memory caches will only work if the application preserves the + PAM environment between the calls to `pam_authenticate` and + `pam_setcred`. Most do, but OpenSSH notoriously does not and calls + `pam_authenticate` in a subprocess, so this method is used to pass the + tickets to the `pam_setcred` call in a different process. + + `pam_authenticate` does a complete authentication, including checking + the resulting TGT by obtaining a service ticket for the local host if + possible, but this requires read access to the system keytab. If the + keytab doesn't exist, can't be read, or doesn't include the appropriate + credentials, the default is to accept the authentication. This can be + controlled by setting `verify_ap_req_nofail` to true in `[libdefaults]` + in `/etc/krb5.conf`. `pam_authenticate` also does a basic authorization + check, by default calling `krb5_kuserok` (which uses `~/.k5login` if + available and falls back to checking that the principal corresponds to + the account name). This can be customized with several options + documented in the pam_krb5(5) man page. + + pam-krb5 treats `pam_open_session` and `pam_setcred(PAM_ESTABLISH_CRED)` + as synonymous, as some applications call one and some call the other. + Both copy the initial credentials from the temporary cache into a + permanent cache for this session and set `KRB5CCNAME` in the + environment. It will remember when the credential cache has been + established and then avoid doing any duplicate work afterwards, since + some applications call `pam_setcred` or `pam_open_session` multiple + times (most notably X.Org 7 and earlier xdm, which also throws away the + module settings the last time it calls them). + + `pam_acct_mgmt` finds the ticket cache, reads it in to obtain the + authenticated principal, and then does is another authorization check + against `.k5login` or the local account name as described above. + + After the call to `pam_setcred` or `pam_open_session`, the ticket cache + will be destroyed whenever the calling application either destroys the + PAM environment or calls `pam_close_session`, which it should do on user + logout. + + The normal sequence of events when refreshing a ticket cache (such as + inside a screensaver) is: + + ``` + pam_authenticate + pam_setcred(PAM_REINITIALIZE_CRED) + pam_acct_mgmt + ``` + + (`PAM_REFRESH_CRED` may be used instead.) Authentication proceeds as + above. At the `pam_setcred` stage, rather than creating a new ticket + cache, the module instead finds the current ticket cache (from the + `KRB5CCNAME` environment variable or the default ticket cache location + from the Kerberos library) and then reinitializes it with the + credentials from the temporary `pam_authenticate` ticket cache. When + refreshing a ticket cache, the application should not open a session. + Calling `pam_acct_mgmt` is optional; pam-krb5 doesn't do anything + different when it's called in this case. + + If `pam_authenticate` apparently didn't succeed, or if an account was + configured to be ignored via `ignore_root` or `minimum_uid`, + `pam_setcred` (and therefore `pam_open_session`) and `pam_acct_mgmt` + return `PAM_IGNORE`, which tells the PAM library to proceed as if that + module wasn't listed in the PAM configuration at all. + `pam_authenticate`, however, returns failure in the ignored user case by + default, since otherwise a configuration using `ignore_root` with + pam-krb5 as the only PAM module would allow anyone to log in as root + without a password. There doesn't appear to be a case where returning + `PAM_IGNORE` instead would improve the module's behavior, but if you + know of a case, please let me know. + + By default, `pam_authenticate` intentionally does not follow the PAM + standard for handling expired accounts and instead returns failure from + `pam_authenticate` unless the Kerberos libraries are able to change the + account password during authentication. Too many applications either do + not call `pam_acct_mgmt` or ignore its exit status. The fully correct + PAM behavior (returning success from `pam_authenticate` and + `PAM_NEW_AUTHTOK_REQD` from `pam_acct_mgmt`) can be enabled with the + `defer_pwchange` option. + + The `defer_pwchange` option is unfortunately somewhat tricky to + implement. In this case, the calling sequence is: + + ``` + pam_authenticate + pam_acct_mgmt + pam_chauthtok + pam_setcred + pam_open_session + ``` + + During the first `pam_authenticate`, we can't obtain credentials and + therefore a ticket cache since the password is expired. But + `pam_authenticate` isn't called again after `pam_chauthtok`, so + `pam_chauthtok` has to create a ticket cache. We however don't want it + to do this for the normal password change (`passwd`) case. + + What we do is set a flag in our PAM data structure saying that we're + processing an expired password, and `pam_chauthtok`, if it sees that + flag, redoes the authentication with password prompting disabled after + it finishes changing the password. + + Unfortunately, when handling password changes this way, `pam_chauthtok` + will always have to prompt the user for their current password again + even though they just typed it. This is because the saved + authentication tokens are cleared after `pam_authenticate` returns, for + security reasons. We could hack around this by saving the password in + our PAM data structure, but this would let the application gain access + to it (exactly what the clearing is intended to prevent) and breaks a + PAM library guarantee. We could also work around this by having + `pam_authenticate` get the `kadmin/changepw` authenticator in the + expired password case and store it for `pam_chauthtok`, but it doesn't + seem worth the hassle. + - title: History and Acknowledgements + body: | + Originally written by Frank Cusack , with the + following acknowledgement: + + > Thanks to Naomaru Itoi , Curtis King + > , and Derrick Brashear , all + > of whom have written and made available Kerberos 4/5 modules. + > Although no code in this module is directly from these author's + > modules, (except the get_user_info() routine in support.c; derived + > from whichever of these authors originally wrote the first module the + > other 2 copied from), it was extremely helpful to look over their code + > which aided in my design. + + The module was then patched for the FreeBSD ports collection with + additional modifications by unknown maintainers and then was modified by + Joel Kociolek to be usable with Debian GNU/Linux. + + It was packaged by Sam Hartman as the Kerberos v5 PAM module for Debian + and improved and modified by him and later by Russ Allbery to fix bugs + and add additional features. It was then adopted by Andres Salomon, who + added support for refreshing credentials. + + The current distribution is maintained by Russ Allbery, who also added + support for reading configuration from `krb5.conf`, added many features + for compatibility with the Sourceforge module, commented and + standardized the formatting of the code, and overhauled the + documentation. + + Thanks to Douglas E. Engert for the initial implementation of PKINIT + support. I have since modified and reworked it extensively, so any bugs + or compilation problems are my fault. + + Thanks to Markus Moeller for lots of debugging and multiple patches and + suggestions for improved portability. + + Thanks to Booker Bense for the implementation of the `alt_auth_map` + option. + + Thanks to Sam Hartman for the FAST support implementation. diff --git a/docs/pam_krb5.pod b/docs/pam_krb5.pod new file mode 100644 index 000000000000..024584dfd4cd --- /dev/null +++ b/docs/pam_krb5.pod @@ -0,0 +1,1056 @@ +=for stopwords +KRB5CCNAME ChallengeResponseAuthentication GSS-API Heimdal KDC PKINIT +PasswordAuthentication SRV Solaris Sourceforge aname appdefaults auth +canonicalized ccache krb5.conf forwardable kdestroy keytab libdefaults +logout pam-krb5 preauth 0.8rc1 screensaver screensavers sshd localname +krb5.conf. 0.8rc1. Allbery Cusack Salomon FSFAP SPDX-License-Identifier +responder + +=head1 NAME + +pam_krb5 - Kerberos PAM module + +=head1 SYNOPSIS + + auth sufficient pam_krb5.so minimum_uid=1000 + session required pam_krb5.so minimum_uid=1000 + account required pam_krb5.so minimum_uid=1000 + password sufficient pam_krb5.so minimum_uid=1000 + +=head1 DESCRIPTION + +The Kerberos service module for PAM, typically installed at +F, provides functionality for the four PAM +operations: authentication, account management, session management, and +password management. F is a shared object that is +dynamically loaded by the PAM subsystem as necessary, based on the system +PAM configuration. PAM is a system for plugging in external +authentication and session management modules so that each application +doesn't have to know the best way to check user authentication or create a +user session on that system. For details on how to configure PAM on your +system, see the PAM man page, often pam(7). + +Here are the actions of this module when called from each group: + +=over 4 + +=item auth + +Provides implementations of pam_authenticate() and pam_setcred(). The +former takes the username from the PAM session, prompts for the user's +password (unless configured to use an already-entered password), and then +performs a Kerberos initial authentication, storing the obtained +credentials (if successful) in a temporary ticket cache. The latter, +depending on the flags it is called with, either takes the contents of the +temporary ticket cache and writes it out to a persistent ticket cache +owned by the user or uses the temporary ticket cache to refresh an +existing user ticket cache. + +Passwords as long or longer than PAM_MAX_RESP_SIZE octets (normally 512 +octets) will be rejected, since excessively long passwords can be used as +a denial of service attack. + +After doing the initial authentication, the Kerberos PAM module will +attempt to obtain tickets for a key in the local system keytab and then +verify those tickets. Unless this step is performed, the authentication +is vulnerable to KDC spoofing, but it requires that the system have a +local key and that the PAM module be running as a user that can read the +keytab file (normally F. You can point the Kerberos PAM +module at a different keytab with the I option. If that keytab +cannot be read or if no keys are found in it, the default (potentially +insecure) behavior is to skip this check. If you want to instead fail +authentication if the obtained tickets cannot be checked, set +C to true in the [libdefaults] section of +F. Note that this will affect applications other than +this PAM module. + +By default, whenever the user is authenticated, a basic authorization +check will also be done using krb5_kuserok(). The default behavior of +this function is to check the user's account for a F<.k5login> file and, +if one is present, ensure that the user's principal is listed in that +file. If F<.k5login> is not present, the default check is to ensure that +the user's principal is in the default local realm and the user portion of +the principal matches the account name (this can be changed by configuring +a custom aname to localname mapping in F; see the Kerberos +documentation for details). This can be customized with several +configuration options; see below. + +If the username provided to PAM contains an C<@> and Kerberos can, +treating the username as a principal, map it to a local account name, +pam_authenticate() will change the PAM user to that local account name. +This allows users to log in with their Kerberos principal and let Kerberos +do the mapping to an account. This can be disabled with the +I option. Be aware, however, that this facility cannot be +used with OpenSSH. OpenSSH will reject usernames that don't match local +accounts before this remapping can be done and will pass an invalid +password to the PAM module. Also be aware that several other common PAM +modules, such as pam_securetty, expect to be able to look up the user with +getpwnam() and cannot be called before pam_krb5 when using this feature. + +When pam_setcred() is called to initialize a new ticket cache, the +environment variable KRB5CCNAME is set to the path to that ticket cache. +By default, the cache will be named F where UID is +the user's UID and RANDOM is six randomly-chosen letters. This can be +configured with the I and I options. + +pam-krb5 does not use the default ticket cache location or +I in the C<[libdefaults]> section of F. The +default cache location would share a cache for all sessions of the same +user, which causes confusing behavior when the user logs out of one of +multiple sessions. + +If pam_setcred() initializes a new ticket cache, it will also set up that +ticket cache so that it will be deleted when the PAM session is closed. +Normally, the calling program (B, B, etc.) will run the +user's shell as a sub-process, wait for it to exit, and then close the PAM +session, thereby cleaning up the user's session. + +=item session + +Provides implementations of pam_open_session(), which is equivalent to +calling pam_setcred() with the PAM_ESTABLISH_CRED flag, and +pam_close_session(), which destroys the ticket cache created by +pam_setcred(). + +=item account + +Provides an implementation of pam_acct_mgmt(). All it does is do the same +authorization check as performed by the pam_authenticate() implementation +described above. + +=item password + +Provides an implementation of pam_chauthtok(), which implements password +changes. The user is prompted for their existing password (unless +configured to use an already entered one) and the PAM module then obtains +credentials for the special Kerberos principal C. It +then prompts the user for a new password, twice to ensure that the user +entered it properly (again, unless configured to use an already entered +password), and then does a Kerberos password change. + +Passwords as long or longer than PAM_MAX_RESP_SIZE octets (normally 512 +octets) will be rejected, since excessively long passwords can be used as +a denial of service attack. + +Unlike the normal Unix password module, this module will allow any user to +change any other user's password if they know the old password. Also, +unlike the normal Unix password module, root will always be prompted for +the old password, since root has no special status in Kerberos. (To +change passwords in Kerberos without knowing the old password, use +kadmin(8) instead.) + +=back + +Both the account and session management calls of the Kerberos PAM module +will return PAM_IGNORE if called in the context of a PAM session for a +user who did not authenticate with Kerberos (a return code of C in +the Linux PAM configuration language). + +Note that this module assumes the network is available in order to do a +Kerberos authentication. If the network is not available, some Kerberos +libraries have timeouts longer than the timeout imposed by the login +process. This means that using this module incautiously can make it +impossible to log on to console as root. For this reason, you should +always use the I or I options, list a local +authentication module such as B first with a control field of +C so that the Kerberos PAM module will be skipped if local +password authentication was successful. + +This is not the same PAM module as the Kerberos PAM module available from +Sourceforge, or the one included on Red Hat systems. It supports many of +the same options, has some additional options, and doesn't support some of +the options those modules do. + +=head1 CONFIGURATION + +The Kerberos PAM module takes many options, not all of which are relevant +to every PAM group; options that are not relevant will be silently +ignored. Any of these options can be set in the PAM configuration as +arguments listed after C. Some of the options can also be +set in the system F file; if this is possible, it will be noted +below in the option description. + +To set a boolean option in the PAM configuration file, just give the name +of the option in the arguments. To set an option that takes an argument, +follow the option name with an equal sign (=) and the value, with no +separating whitespace. Whitespace in option arguments is not supported in +the PAM configuration. + +To set an option for the PAM module in the system F file, put +that option in the C<[appdefaults]> section. All options must be followed +by an equal sign (=) and a value, so for boolean options add C<= true>. +The Kerberos PAM module will look for options either at the top level of +the C<[appdefaults]> section or in a subsection named C, inside or +outside a section for the realm. For example, the following fragment of a +F file would set I to true, I to +1000, and set I only if the realm is EXAMPLE.COM. + + [appdefaults] + forwardable = true + pam = { + minimum_uid = 1000 + EXAMPLE.COM = { + ignore_k5login = true + } + } + +For more information on the syntax of F, see krb5.conf(5). +Note that options that depend on the realm will be set only on the basis +of the default realm, either as configured in krb5.conf(5) or as set by +the I option described below. If the user authenticates to an +account qualified with a realm, that realm will not be used when +determining which options will apply. + +There is no difference to the PAM module whether options are specified at +the top level or in a C section; the C section is supported in +case there are options that should be set for the PAM module but not for +other applications. + +If the same option is set in F and in the PAM configuration, +the latter takes precedent. Note, however, that due to the configuration +syntax, there's no way to turn off a boolean option in the PAM +configuration that was turned on in F. + +The start of each option description is annotated with the version of +pam-krb5 in which that option was added with the current meaning. + +=head2 Authorization + +=over 4 + +=item alt_auth_map= + +[3.12] This functions similarly to the I option. The + argument is used as the authentication Kerberos principal, with +any C<%s> in replaced with the username. If the username +contains an C<@>, only the part of the username before the realm is used +to replace C<%s>. If contains a realm, it will be used; +otherwise, the realm of the username (if any) will be appended to the +result. There is no quote removal. + +If this option is present, the default behavior is to try this alternate +principal first and then fall back to the standard behavior if it fails. +The primary usage is to allow alternative principals to be used for +authentication in programs like B. Most examples will look like: + + alt_auth_map=%s/root + +which attempts authentication as the root instance of the username first +and then falls back to the regular username (but see I and +I). + +This option also allows a cheap way to attempt authentication in an +alternative realm first and then fall back to the primary realm. A +setting like: + + alt_auth_map=%s@EXAMPLE.COM + +will attempt authentication in the EXAMPLE.COM realm first and then fall +back on the local default realm. This is more convenient than running the +module multiple times with multiple default realms set with I, but +it is very limited: only two realms can be tried, and the alternate realm +is always tried first. + +This option can be set in C<[appdefaults]> in F, although +normally it doesn't make sense to do that; normally it is used in the PAM +options of configuration for specific programs. It is only applicable to +the auth and account groups. If this option is set for the auth group, be +sure to set it for the account group as well or account authorization may +fail. + +=item force_alt_auth + +[3.12] This option is used with I and forces authentication +as the mapped principal if that principal exists in the KDC. Only if the +KDC returns principal unknown does the Kerberos PAM module fall back to +normal authentication. This can be used to force authentication with an +alternate instance. If I is not set, it has no effect. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item ignore_k5login + +[2.0] Never look for a F<.k5login> file in the user's home directory. +Instead, only check that the Kerberos principal maps to the local account +name. The default check is to ensure the realm matches the local realm +and the user portion of the principal matches the local account name, but +this can be customized by setting up an aname to localname mapping in +F. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and account groups. + +=item ignore_root + +[1.1] Do not do anything if the username is C. The authentication +and password calls will silently fail (allowing that status to be ignored +via a control of C or C), and the account and +session calls (including pam_setcred) will return PAM_IGNORE, telling the +PAM library to proceed as if they weren't mentioned in the PAM +configuration. This option is supported and will remain, but normally you +want to use I instead. + +This option can be set in C<[appdefaults]> in F. + +=item minimum_uid= + +[2.0] Do not do anything if the authenticated account name corresponds to +a local account and that local account has a UID lower than . If +both of those conditions are true, the authentication and password calls +will silently fail (allowing that status to be ignored via a control of +C or C), and the account and session calls +(including pam_setcred) will return PAM_IGNORE, telling the PAM library to +proceed as if they weren't mentioned in the PAM configuration. + +Using this option is highly recommended if you don't need to use Kerberos +to authenticate password logins to the root account (which isn't +recommended since Kerberos requires a network connection). It provides +some defense in depth against user principals that happen to match a +system account incorrectly authenticating as that system account. + +This option can be set in C<[appdefaults]> in F. + +=item only_alt_auth + +[3.12] This option is used with I and forces the use of the +mapped principal for authentication. It disables fallback to normal +authentication in all cases and overrides I and +I. If I is not set, it has no effect and +the standard authentication behavior is used. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item search_k5login + +[2.0] Normally, the Kerberos implementation of pam_authenticate attempts +to obtain tickets for the authenticating username in the local realm. If +this option is set and the local user has a F<.k5login> file in their home +directory, the module will instead open and read that F<.k5login> file, +attempting to use the supplied password to authenticate as each principal +listed there in turn. If any of those authentications succeed, the user +will be successfully authenticated; otherwise, authentication will fail. +This option is useful for allowing password authentication (via console or +B without GSS-API support) to shared accounts. If there is no +F<.k5login> file, the behavior is the same as normal. Using this option +requires that the user's F<.k5login> file be readable at the time of +authentication. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=back + +=head2 Kerberos Behavior + +=over 4 + +=item anon_fast + +[4.6] Attempt to use Flexible Authentication Secure Tunneling (FAST) by +first authenticating as the anonymous user (WELLKNOWN/ANONYMOUS) and using +its credentials as the FAST armor. This requires anonymous PKINIT be +enabled for the local realm, that PKINIT be configured on the local +system, and that the Kerberos library support FAST and anonymous PKINIT. + +FAST is a mechanism to protect Kerberos against password guessing attacks +and provide other security improvements. To work, FAST requires that a +ticket be obtained with a strong key to protect exchanges with potentially +weaker user passwords. This option uses anonymous authentication to +obtain that key and then uses it to protect the subsequent authentication. + +If anonymous PKINIT is not available or fails, FAST will not be used and +the authentication will proceed as normal. + +To instead use an existing ticket cache for the FAST credentials, use +I instead of this option. If both I and +I are set, the ticket cache named by I will be +tried first, and the Kerberos PAM module will fall back on attempting +anonymous PKINIT if that cache could not be used. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and password groups. + +The operation is the same as if using the I option, but the +cache is created and destroyed automatically. If both I and +I options are used, the I takes precedent and no +anonymous authentication is done. + +=item fast_ccache= + +[4.3] The same as I, but use an existing Kerberos ticket cache +rather than anonymous PKINIT. This allows use of FAST with a realm that +doesn't support PKINIT or doesn't support anonymous authentication. + + should be a credential cache containing a ticket obtained +using a strong key, such as the randomized key for the host principal of +the local system. If names a ticket cache that is readable +by the authenticating process and has tickets then FAST will be attempted. +The easiest way to use this option is to use a program like B to +maintain a ticket cache using the host's keytab. This ticket cache should +normally only be readable by root, so this option will not be able to +protect authentications done as non-root users (such as screensavers). + +If no credentials are present in the ticket cache, or if the ticket cache +does not exist or is not readable, FAST will not used and authentication +will proceed as normal. However, if the credentials in that ticket cache +are expired, authentication will fail if the KDC supports FAST. + +To use anonymous PKINIT to protect the FAST exchange, use the I +option instead. I is easier to configure, since no existing +ticket cache is required, but requires PKINIT be available and configured +and that the local realm support anonymous authentication. If both +I and I are set, the ticket cache named by +I will be tried first, and the Kerberos PAM module will fall +back on attempting anonymous PKINIT if that cache could not be used. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and password groups. + +=item forwardable + +[1.0] Obtain forwardable tickets. If set (to either true or false, +although it can only be set to false in F), this overrides the +Kerberos library default set in the [libdefaults] section of F. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item keytab= + +[3.0] Specifies the keytab to use when validating the user's credentials. +The default is the default system keytab (normally F), +which is usually only readable by root. Applications not running as root +that use this PAM module for authentication may wish to point it to +another keytab the application can read. The first principal found in the +keytab will be used as the principal for credential verification. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item realm= + +[2.2] Set the default Kerberos realm and obtain credentials in that realm, +rather than in the normal default realm for this system. If this option +is used, it should be set for all groups being used for consistent +results. This setting will affect authorization decisions since it +changes the default realm. This setting will also change the service +principal used to verify the obtained credentials to be in the specified +realm. + +If you only want to set the realm assumed for user principals without +changing the realm for authorization decisions or the service principal +used to verify credentials, see the I option. + +=item renew_lifetime= + +[2.0] Obtain renewable tickets with a maximum renewable lifetime of +. should be a Kerberos lifetime string such as +C<2d4h10m> or a time in minutes. If set, this overrides the Kerberos +library default set in the [libdefaults] section of F. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item ticket_lifetime= + +[3.0] Obtain tickets with a maximum lifetime of . +should be a Kerberos lifetime string such as C<2d4h10m> or a time in +minutes. If set, this overrides the Kerberos library default set in the +[libdefaults] section of F. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item user_realm + +[4.6] Obtain credentials in the specified realm rather than in the default +realm for this system. If this option is used, it should be set for all +groups being used for consistent results (although the account group +currently doesn't care about realm). This will not change authorization +decisions. If the obtained credentials are supposed to allow access to a +shell account, the user will need an appropriate F<.k5login> file entry or +the system will have to have a custom aname_to_localname mapping. + +=back + +=head2 PAM Behavior + +=over 4 + +=item clear_on_fail + +[3.9] When changing passwords, PAM first does a preliminary check through +the complete password stack, and then calls each module again to do the +password change. After that preliminary check, the order of module +invocation is fixed. This means that even if the Kerberos password change +fails (or if one of the other password changes in the stack fails), other +password PAM modules in the stack will still be called even if the failing +module is marked required or requisite. When using multiple password PAM +modules to synchronize passwords between multiple systems when they +change, this behavior can cause unwanted differences between the +environments. + +Setting this option provides a way to work around this behavior. If this +option is set and a Kerberos password change is attempted and fails (due +to network errors or password strength checking on the KDC, for example), +this module will clear the stored password in the PAM stack. This will +force any subsequent modules that have I set to fail so that +those environments won't get out of sync with the password in Kerberos. +The Kerberos PAM module will not meddle with the stored password if it +skips the user due to configuration such as minimum_uid. + +Unfortunately, setting this option interferes with other desirable PAM +configurations, such as attempting to change the password in Kerberos +first and falling back on the local Unix password database if that fails. +It therefore isn't the default. Turn it on (and list pam_krb5 first after +pam_cracklib if used) when synchronizing passwords between multiple +environments. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the password group. + +=item debug + +[1.0] Log more verbose trace and debugging information to syslog at +LOG_DEBUG priority, including entry and exit from each of the external PAM +interfaces (except pam_close_session). + +This option can be set in C<[appdefaults]> in F. + +=item defer_pwchange + +[3.11] By default, pam-krb5 lets the Kerberos library handle prompting for +a password change if an account's password is expired during the auth +group. If this fails, pam_authenticate() returns an error. + +According to the PAM standard, this is not the correct way to handle +expired passwords. Instead, pam_authenticate() should return success +without attempting a password change, and then pam_acct_mgmt() should +return PAM_NEW_AUTHTOK_REQD, at which point the calling application is +responsible for either rejecting the authentication or calling +pam_chauthtok(). However, following the standard requires that all +applications call pam_acct_mgmt() and check its return status; otherwise, +expired accounts may be able to successfully authenticate. Many +applications do not do this. + +If this option is set, pam-krb5 uses the fully correct PAM mechanism for +handling expired accounts instead of failing in pam_authenticate(). Due +to the security risk of widespread broken applications, be very careful +about enabling this option. It should normally only be turned on to solve +a specific problem (such as using Solaris Kerberos libraries that don't +support prompting for password changes during authentication), and then +only for specific applications known to call pam_acct_mgmt() and check its +return status properly. + +This option is only supported when pam-krb5 is built with MIT Kerberos. +If built against Heimdal, this option does nothing and normal expired +password change handling still happens. (Heimdal is missing the required +API to implement this option, at least as of version 1.6.) + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item fail_pwchange + +[4.2] By default, pam-krb5 lets the Kerberos library handle prompting for +a password change if an account's password is expired during the auth +group. If this option is set, expired passwords are instead treated as an +authentication failure identical to an incorrect password. Also see +I and I. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item force_pwchange + +[3.11] If this option is set and authentication fails with a Kerberos +error indicating the user's password is expired, attempt to immediately +change their password during the authenticate step. Under normal +circumstances, this is unnecessary. Most Kerberos libraries will do this +for you, and setting this option will prompt the user twice to change +their password if the first attempt (done by the Kerberos library) fails. +However, some system Kerberos libraries (such as Solaris's) have password +change prompting disabled in the Kerberos library; on those systems, you +can set this option to simulate the normal library behavior. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item no_update_user + +[4.7] Normally, if pam-krb5 is able to canonicalize the principal to a +local name using krb5_aname_to_localname() or similar calls, it changes +the PAM_USER variable for this PAM session to the canonicalized local +name. Setting this option disables this behavior and leaves PAM_USER set +to the initial authentication identity. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth group. + +=item silent + +[1.0] Don't show messages and errors from Kerberos, such as warnings of +expiring passwords, to the user via the prompter. This is equivalent to +the behavior when the application passes in PAM_SILENT, but can be set in +the PAM configuration. + +This option is only applicable to the auth and password groups. + +=item trace= + +[4.6] Enables Kerberos library trace logging to the specified log file if +it is supported by the Kerberos library. This is intended for temporary +debugging. The specified file will be appended to without further +security checks, so do not specify a file in a publicly writable directory +like F. + +=back + +=head2 PKINIT + +=over 4 + +=item pkinit_anchors= + +[3.0] When doing PKINIT authentication, use as the client trust +anchors. This is normally a reference to a file containing the trusted +certificate authorities. This option is only used if I or +I are set. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and password groups. + +=item pkinit_prompt + +[3.0] Before attempting PKINIT authentication, prompt the user to insert a +smart card. You may want to set this option for programs such as +B that call PAM as soon as the mouse is touched and +don't give the user an opportunity to enter the smart card first. Any +information entered at the first prompt is ignored. If I is +set, a user who wishes to use a password instead can just press Enter and +then enter their password as normal. This option is only used if +I or I are set. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and password groups. + +=item pkinit_user= + +[3.0] When doing PKINIT authentication, use as the user ID. The +value of this string is highly dependent on the type of PKINIT +implementation you're using, but will generally be something like: + + PKCS11:/usr/lib/pkcs11/lib/soft-pkcs11.so + +to specify the module to use with a smart card. It may also point to a +user certificate or to other types of user IDs. See the Kerberos library +documentation for more details. This option is only used if I +or I are set. + +This option can be set in C<[appdefaults]> in F and is only +applicable to the auth and password groups. + +=item preauth_opt=