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=