INN commit: branches/2.6 (4 files)
INN Commit
rra at isc.org
Sat Mar 10 14:59:28 UTC 2018
Date: Saturday, March 10, 2018 @ 06:59:27
Author: iulius
Revision: 10266
Stop using com_err directly
com_err is an obsolete way of reporting Kerberos errors. Add some
additional Kerberos portability code from rra-c-util to allow using
krb5_get_error_message, which is the modern approach, and remove the
additional probing for com_err.h.
Also, if --with-krb5 (or the equivalent for other probes) is given and a
krb5-config was found at the install root, skip the PATH search for
krb5-config to avoid confusing output. This results in redoing the
probe and using cached output when testing multiple krb5-config
features, but that seems better than the confusing output.
Patch from Russ Allbery.
Modified:
branches/2.6/authprogs/auth_krb5.c
branches/2.6/configure.ac
branches/2.6/lib/Makefile
branches/2.6/m4/krb5-config.m4
-----------------------+
authprogs/auth_krb5.c | 139 ++++++++++++++++++++++++++++++++++++++++--------
configure.ac | 14 ----
lib/Makefile | 7 +-
m4/krb5-config.m4 | 8 +-
4 files changed, 126 insertions(+), 42 deletions(-)
Modified: authprogs/auth_krb5.c
===================================================================
--- authprogs/auth_krb5.c 2018-03-10 14:53:01 UTC (rev 10265)
+++ authprogs/auth_krb5.c 2018-03-10 14:59:27 UTC (rev 10266)
@@ -1,13 +1,13 @@
/* $Id$
**
-** Check an username and password against Kerberos v5.
+** Check an username and password against Kerberos.
**
** Based on nnrpkrb5auth by Christopher P. Lindsey <lindsey at mallorn.com>
** See <http://www.mallorn.com/tools/nnrpkrb5auth>
**
** This program takes a username and password pair from nnrpd and checks
-** checks their validity against a Kerberos v5 KDC by attempting to obtain a
-** TGT. With the -i <instance> command line option, appends /<instance> to
+** their validity against a Kerberos KDC by attempting to obtain a TGT.
+** With the -i <instance> command line option, appends /<instance> to
** the username prior to authentication.
**
** Special thanks to Von Welch <vwelch at vwelch.com> for giving me the initial
@@ -21,28 +21,123 @@
#include "config.h"
#include "clibrary.h"
#include "libauth.h"
-#ifdef HAVE_ET_COM_ERR_H
-# include <et/com_err.h>
-#elif defined(HAVE_KERBEROSV5_COM_ERR_H)
-# include <kerberosv5/com_err.h>
-#else
-# include <com_err.h>
-#endif
-#ifdef HAVE_KRB5_H
+#if defined(HAVE_KRB5_H)
# include <krb5.h>
-#elif HAVE_KERBEROSV5_KRB5_H
+#elif defined(HAVE_KERBEROSV5_KRB5_H)
# include <kerberosv5/krb5.h>
#else
# include <krb5/krb5.h>
#endif
+/* Figure out what header files to include for error reporting. */
+#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) && !defined(HAVE_KRB5_GET_ERR_TEXT)
+# if !defined(HAVE_KRB5_GET_ERROR_STRING)
+# if defined(HAVE_IBM_SVC_KRB5_SVC_H)
+# include <ibm_svc/krb5_svc.h>
+# elif defined(HAVE_ET_COM_ERR_H)
+# include <et/com_err.h>
+# elif defined(HAVE_KERBEROSV5_COM_ERR_H)
+# include <kerberosv5/com_err.h>
+# else
+# include <com_err.h>
+# endif
+# endif
+#endif
+
#include "inn/messages.h"
#include "inn/libinn.h"
+#include "inn/xmalloc.h"
/*
+ * This string is returned for unknown error messages. We use a static
+ * variable so that we can be sure not to free it.
+ */
+#if !defined(HAVE_KRB5_GET_ERROR_MESSAGE) \
+ || !defined(HAVE_KRB5_FREE_ERROR_MESSAGE)
+static const char error_unknown[] = "unknown error";
+#endif
+
+
+#ifndef HAVE_KRB5_GET_ERROR_MESSAGE
+/*
+ * Given a Kerberos error code, return the corresponding error. Prefer the
+ * Kerberos interface if available since it will provide context-specific
+ * error information, whereas the error_message() call will only provide a
+ * fixed message.
+ */
+const char *
+krb5_get_error_message(krb5_context ctx UNUSED, krb5_error_code code UNUSED)
+{
+ const char *msg;
+
+# if defined(HAVE_KRB5_GET_ERROR_STRING)
+ msg = krb5_get_error_string(ctx);
+# elif defined(HAVE_KRB5_GET_ERR_TEXT)
+ msg = krb5_get_err_text(ctx, code);
+# elif defined(HAVE_KRB5_SVC_GET_MSG)
+ krb5_svc_get_msg(code, (char **) &msg);
+# else
+ msg = error_message(code);
+# endif
+ if (msg == NULL)
+ return error_unknown;
+ else
+ return msg;
+}
+#endif /* !HAVE_KRB5_GET_ERROR_MESSAGE */
+
+
+#ifndef HAVE_KRB5_FREE_ERROR_MESSAGE
+/*
+ * Free an error string if necessary. If we returned a static string, make
+ * sure we don't free it.
+ *
+ * This code assumes that the set of implementations that have
+ * krb5_free_error_message is a subset of those with krb5_get_error_message.
+ * If this assumption ever breaks, we may call the wrong free function.
+ */
+void
+krb5_free_error_message(krb5_context ctx UNUSED, const char *msg)
+{
+ if (msg == error_unknown)
+ return;
+# if defined(HAVE_KRB5_GET_ERROR_STRING)
+ krb5_free_error_string(ctx, (char *) msg);
+# elif defined(HAVE_KRB5_SVC_GET_MSG)
+ krb5_free_string(ctx, (char *) msg);
+# endif
+}
+#endif /* !HAVE_KRB5_FREE_ERROR_MESSAGE */
+
+
+/*
+** Report a Kerberos error to standard error.
+*/
+static void __attribute__((__format__(printf, 3, 4)))
+warn_krb5(krb5_context ctx, krb5_error_code code, const char *format, ...)
+{
+ const char *k5_msg;
+ char *message;
+ va_list args;
+
+ k5_msg = krb5_get_error_message(ctx, code);
+ va_start(args, format);
+ xvasprintf(&message, format, args);
+ va_end(args);
+ if (k5_msg == NULL)
+ warn("%s", message);
+ else
+ warn("%s: %s", message, k5_msg);
+ free(message);
+ if (k5_msg != NULL)
+ krb5_free_error_message(ctx, k5_msg);
+}
+
+
+/*
** Check the username and password by attempting to get a TGT. Returns 1 on
-** success and 0 on failure. Errors are reported via com_err.
+** success and 0 on failure.
*/
static int
krb5_check_password(const char *principal, const char *password)
@@ -57,13 +152,12 @@
code = krb5_init_context(&ctx);
if (code != 0) {
- com_err(message_program_name, code, "initializing krb5 context");
+ warn_krb5(NULL, code, "cannot initialize Kerberos");
return 0;
}
code = krb5_parse_name(ctx, principal, &princ);
if (code != 0) {
- com_err(message_program_name, code, "parsing principal name %.100s",
- principal);
+ warn_krb5(ctx, code, "cannot parse principal %.100s", principal);
goto cleanup;
}
memset(&opts, 0, sizeof(opts));
@@ -85,16 +179,15 @@
else {
switch (code) {
case KRB5KRB_AP_ERR_BAD_INTEGRITY:
- com_err(message_program_name, 0, "bad password for %.100s",
- principal);
+ warn("bad password for %.100s", principal);
break;
case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN:
- com_err(message_program_name, 0, "unknown user %.100s",
- principal);
+ warn("unknown user %.100s", principal);
break;
default:
- com_err(message_program_name, code,
- "checking Kerberos password for %.100s", principal);
+ warn_krb5(ctx, code, "Kerberos authentication for %.100s failed",
+ principal);
+ break;
}
}
@@ -132,7 +225,7 @@
/* May need to prepend instance name if -i option was given. */
if (argc > 1) {
if (argc == 3 && strcmp(argv[1], "-i") == 0) {
- new_user = concat(authinfo->username, "/", argv[2], (char *) 0);
+ xasprintf(&new_user, "%s/%s", authinfo->username, argv[2]);
free(authinfo->username);
authinfo->username = new_user;
} else {
Modified: configure.ac
===================================================================
--- configure.ac 2018-03-10 14:53:01 UTC (rev 10265)
+++ configure.ac 2018-03-10 14:59:27 UTC (rev 10266)
@@ -394,18 +394,8 @@
INN_LIB_ZLIB_OPTIONAL
dnl If Kerberos is found, define KRB5_AUTH to auth_krb5 so as to build
-dnl that program. In case neither et/com_err.h nor kerberosv5/com_err.h
-dnl nor com_err.h can be found and --with-krb5 is not given, do not define
-dnl KRB5_AUTH and clear the other variables set for Kerberos support.
-AS_IF([test x"$inn_use_KRB5" = xtrue],
- [AC_CHECK_HEADERS([et/com_err.h], [KRB5_AUTH=auth_krb5],
- [AC_CHECK_HEADERS([kerberosv5/com_err.h], [KRB5_AUTH=auth_krb5],
- [AC_CHECK_HEADERS([com_err.h], [KRB5_AUTH=auth_krb5],
- [AS_IF([test x"$with_krb5" = x],
- [KRB5_CPPFLAGS=
- KRB5_LDFLAGS=
- KRB5_LIBS=],
- [AC_MSG_ERROR([cannot find usable com_err header])])])])])])
+dnl that program.
+AS_IF([test x"$inn_use_KRB5" = xtrue], [KRB5_AUTH=auth_krb5])
AC_SUBST([KRB5_AUTH])
dnl If Berkeley DB is found, check the presence of its header and whether the
Modified: lib/Makefile
===================================================================
--- lib/Makefile 2018-03-10 14:53:01 UTC (rev 10265)
+++ lib/Makefile 2018-03-10 14:59:27 UTC (rev 10266)
@@ -225,9 +225,10 @@
../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
../include/inn/defines.h ../include/inn/options.h ../include/clibrary.h \
../include/config.h ../include/inn/macros.h \
- ../include/portable/stdbool.h ../include/inn/libinn.h \
- ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h \
- ../include/inn/paths.h
+ ../include/portable/stdbool.h ../include/portable/socket.h \
+ ../include/portable/macros.h ../include/portable/getaddrinfo.h \
+ ../include/portable/getnameinfo.h ../include/inn/libinn.h \
+ ../include/inn/concat.h ../include/inn/xmalloc.h ../include/inn/xwrite.h
getmodaddr.o: getmodaddr.c ../include/config.h ../include/inn/defines.h \
../include/inn/system.h ../include/inn/macros.h \
../include/inn/portable-macros.h ../include/inn/portable-stdbool.h \
Modified: m4/krb5-config.m4
===================================================================
--- m4/krb5-config.m4 2018-03-10 14:53:01 UTC (rev 10265)
+++ m4/krb5-config.m4 2018-03-10 14:59:27 UTC (rev 10266)
@@ -12,7 +12,7 @@
dnl package, available at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
dnl
dnl Written by Russ Allbery <eagle at eyrie.org>
-dnl Copyright 2011-2012
+dnl Copyright 2011-2012, 2018
dnl The Board of Trustees of the Leland Stanford Junior University
dnl
dnl This file is free software; the authors give unlimited permission to copy
@@ -78,12 +78,12 @@
dnl krb5-config didn't take an argument to specify the library type, but
dnl always returned the flags for libkrb5.
AC_DEFUN([INN_KRB5_CONFIG],
-[AC_REQUIRE([_INN_KRB5_CONFIG_PATH])
- inn_krb5_config_$3=
+[inn_krb5_config_$3=
inn_krb5_config_$3[]_ok=
AS_IF([test x"$1" != x && test -x "$1/bin/krb5-config"],
[inn_krb5_config_$3="$1/bin/krb5-config"],
- [inn_krb5_config_$3="$PATH_KRB5_CONFIG"])
+ [_INN_KRB5_CONFIG_PATH
+ inn_krb5_config_$3="$PATH_KRB5_CONFIG"])
AS_IF([test x"$inn_krb5_config_$3" != x && test -x "$inn_krb5_config_$3"],
[AC_CACHE_CHECK([for $2 support in krb5-config], [inn_cv_lib_$3[]_config],
[AS_IF(["$inn_krb5_config_$3" 2>&1 | grep $2 >/dev/null 2>&1],
More information about the inn-committers
mailing list