aboutsummaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorCy Schubert <cy@FreeBSD.org>2018-04-03 19:36:00 +0000
committerCy Schubert <cy@FreeBSD.org>2018-04-03 19:36:00 +0000
commitb0e4d68d5124581ae353493d69bea352de4cff8a (patch)
tree43300ec43e83eccd367fd76fdfdefba2dcd7d8f4 /src/include
parent33a9b234e7087f573ef08cd7318c6497ba08b439 (diff)
downloadsrc-b0e4d68d5124581ae353493d69bea352de4cff8a.tar.gz
src-b0e4d68d5124581ae353493d69bea352de4cff8a.zip
Import MIT KRB5 1.16.vendor/krb5/1.16vendor/krb5
Notes
Notes: svn path=/vendor-crypto/krb5/dist/; revision=331939 svn path=/vendor-crypto/krb5/1.16/; revision=331941; tag=vendor/krb5/1.16
Diffstat (limited to 'src/include')
-rw-r--r--src/include/Makefile.in3
-rw-r--r--src/include/autoconf.h.in35
-rw-r--r--src/include/fake-addrinfo.h2
-rw-r--r--src/include/k5-cmocka.h16
-rw-r--r--src/include/k5-input.h6
-rw-r--r--src/include/k5-int.h51
-rw-r--r--src/include/k5-platform.h32
-rw-r--r--src/include/k5-thread.h16
-rw-r--r--src/include/k5-trace.h47
-rw-r--r--src/include/k5-utf8.h61
-rw-r--r--src/include/kdb.h8
-rw-r--r--src/include/kdb_log.h5
-rw-r--r--src/include/krb5/certauth_plugin.h128
-rw-r--r--src/include/krb5/kadm5_auth_plugin.h306
-rw-r--r--src/include/krb5/kdcpolicy_plugin.h128
-rw-r--r--src/include/krb5/kdcpreauth_plugin.h21
-rw-r--r--src/include/krb5/krb5.hin54
-rw-r--r--src/include/net-server.h2
-rw-r--r--src/include/socket-utils.h11
-rw-r--r--src/include/win-mac.h2
20 files changed, 818 insertions, 116 deletions
diff --git a/src/include/Makefile.in b/src/include/Makefile.in
index f5b921833071..cfa5794b72bf 100644
--- a/src/include/Makefile.in
+++ b/src/include/Makefile.in
@@ -140,15 +140,18 @@ install-headers-unix install: krb5/krb5.h profile.h
$(INSTALL_DATA) $(srcdir)/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5.h
$(INSTALL_DATA) $(srcdir)/kdb.h $(DESTDIR)$(KRB5_INCDIR)$(S)kdb.h
$(INSTALL_DATA) krb5/krb5.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)krb5.h
+ $(INSTALL_DATA) $(srcdir)/krb5/certauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)certauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/ccselect_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)ccselect_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/clpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)clpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/hostrealm_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)hostrealm_plugin.h
+ $(INSTALL_DATA) $(srcdir)/krb5/kdcpolicy_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpolicy_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/kdcpreauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kdcpreauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/localauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)localauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/locate_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)locate_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/preauth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)preauth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/pwqual_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)pwqual_plugin.h
+ $(INSTALL_DATA) $(srcdir)/krb5/kadm5_auth_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kadm5_auth_plugin.h
$(INSTALL_DATA) $(srcdir)/krb5/kadm5_hook_plugin.h $(DESTDIR)$(KRB5_INCDIR)$(S)krb5$(S)kadm5_hook_plugin.h
$(INSTALL_DATA) profile.h $(DESTDIR)$(KRB5_INCDIR)$(S)profile.h
$(INSTALL_DATA) $(srcdir)/gssapi.h $(DESTDIR)$(KRB5_INCDIR)$(S)gssapi.h
diff --git a/src/include/autoconf.h.in b/src/include/autoconf.h.in
index b33c5222325e..3dfc128e67bd 100644
--- a/src/include/autoconf.h.in
+++ b/src/include/autoconf.h.in
@@ -62,9 +62,6 @@
#undef GETHOSTBYNAME_R_RETURNS_INT
/* Type of getpeername second argument. */
-#undef GETPEERNAME_ARG2_TYPE
-
-/* Type of getpeername second argument. */
#undef GETPEERNAME_ARG3_TYPE
/* Define if getpwnam_r exists but takes only 4 arguments (e.g., POSIX draft 6
@@ -81,9 +78,6 @@
/* Define if getservbyname_r returns int rather than struct servent * */
#undef GETSERVBYNAME_R_RETURNS_INT
-/* Type of pointer target for argument 2 to getsockname */
-#undef GETSOCKNAME_ARG2_TYPE
-
/* Type of pointer target for argument 3 to getsockname */
#undef GETSOCKNAME_ARG3_TYPE
@@ -124,6 +118,9 @@
/* Define to 1 if you have the `chmod' function. */
#undef HAVE_CHMOD
+/* Define if cmocka library is available. */
+#undef HAVE_CMOCKA
+
/* Define to 1 if you have the `compile' function. */
#undef HAVE_COMPILE
@@ -240,24 +237,9 @@
/* Define to 1 if you have the <lber.h> header file. */
#undef HAVE_LBER_H
-/* Define to 1 if you have the `ldap_explode_dn' function. */
-#undef HAVE_LDAP_EXPLODE_DN
-
/* Define to 1 if you have the <ldap.h> header file. */
#undef HAVE_LDAP_H
-/* Define to 1 if you have the `ldap_initialize' function. */
-#undef HAVE_LDAP_INITIALIZE
-
-/* Define to 1 if you have the `ldap_str2dn' function. */
-#undef HAVE_LDAP_STR2DN
-
-/* Define to 1 if you have the `ldap_unbind_ext_s' function. */
-#undef HAVE_LDAP_UNBIND_EXT_S
-
-/* Define to 1 if you have the `ldap_url_parse_nodn' function. */
-#undef HAVE_LDAP_URL_PARSE_NODN
-
/* Define to 1 if you have the `crypto' library (-lcrypto). */
#undef HAVE_LIBCRYPTO
@@ -333,6 +315,9 @@
/* Define to 1 if you have the `pthread_once' function. */
#undef HAVE_PTHREAD_ONCE
+/* Have PTHREAD_PRIO_INHERIT. */
+#undef HAVE_PTHREAD_PRIO_INHERIT
+
/* Define to 1 if you have the `pthread_rwlock_init' function. */
#undef HAVE_PTHREAD_RWLOCK_INIT
@@ -657,9 +642,6 @@
/* Define to the version of this package. */
#undef PACKAGE_VERSION
-/* Define if pkinit crypto implementation is NSS */
-#undef PKINIT_CRYPTO_IMPL_NSS
-
/* Define if setjmp indicates POSIX interface */
#undef POSIX_SETJMP
@@ -672,7 +654,7 @@
/* Define if termios.h exists and tcsetattr exists */
#undef POSIX_TERMIOS
-/* Define to the necessary symbol if this constant uses a non-standard name on
+/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
#undef PTHREAD_CREATE_JOINABLE
@@ -682,6 +664,9 @@
/* Define as return type of setrpcent */
#undef SETRPCENT_TYPE
+/* The size of `time_t', as computed by sizeof. */
+#undef SIZEOF_TIME_T
+
/* Define for static plugin linkage */
#undef STATIC_PLUGINS
diff --git a/src/include/fake-addrinfo.h b/src/include/fake-addrinfo.h
index 03666a0aaaa7..80ca9f8dfd23 100644
--- a/src/include/fake-addrinfo.h
+++ b/src/include/fake-addrinfo.h
@@ -52,7 +52,7 @@
the data structures and flag values locally.
- On Mac OS X, getaddrinfo results aren't cached (though
+ On macOS, getaddrinfo results aren't cached (though
gethostbyname results are), so we need to build a cache here. Now
things are getting really messy. Because the cache is in use, we
use getservbyname, and throw away thread safety. (Not that the
diff --git a/src/include/k5-cmocka.h b/src/include/k5-cmocka.h
new file mode 100644
index 000000000000..c35b10be0736
--- /dev/null
+++ b/src/include/k5-cmocka.h
@@ -0,0 +1,16 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-cmocka.h - indirect header file for cmocka test programs */
+
+/*
+ * This header conditionally includes cmocka.h, so that "make depend" can work
+ * on cmocka test programs when cmocka isn't available. It also includes the
+ * three system headers required for cmocka.h.
+ */
+
+#include "autoconf.h"
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#ifdef HAVE_CMOCKA
+#include <cmocka.h>
+#endif
diff --git a/src/include/k5-input.h b/src/include/k5-input.h
index d42ebce8f271..9f47fa7ab903 100644
--- a/src/include/k5-input.h
+++ b/src/include/k5-input.h
@@ -33,7 +33,7 @@
#ifndef K5_INPUT_H
#define K5_INPUT_H
-#include "k5-int.h"
+#include "k5-platform.h"
/*
* The k5input module defines helpers for safely consuming a fixed-sized block
@@ -45,7 +45,7 @@
struct k5input {
const unsigned char *ptr;
size_t len;
- krb5_error_code status;
+ int32_t status;
};
static inline void
@@ -59,7 +59,7 @@ k5_input_init(struct k5input *in, const void *ptr, size_t len)
/* Only set the status value of in if it hasn't already been set, so status
* reflects the first thing to go wrong. */
static inline void
-k5_input_set_status(struct k5input *in, krb5_error_code status)
+k5_input_set_status(struct k5input *in, int32_t status)
{
if (!in->status)
in->status = status;
diff --git a/src/include/k5-int.h b/src/include/k5-int.h
index 64991738a3e2..e1b1cb040d5e 100644
--- a/src/include/k5-int.h
+++ b/src/include/k5-int.h
@@ -212,6 +212,7 @@ typedef unsigned char u_char;
#define KRB5_CONF_DNS_URI_LOOKUP "dns_uri_lookup"
#define KRB5_CONF_DOMAIN_REALM "domain_realm"
#define KRB5_CONF_ENABLE_ONLY "enable_only"
+#define KRB5_CONF_ENCRYPTED_CHALLENGE_INDICATOR "encrypted_challenge_indicator"
#define KRB5_CONF_ERR_FMT "err_fmt"
#define KRB5_CONF_EXTRA_ADDRESSES "extra_addresses"
#define KRB5_CONF_FORWARDABLE "forwardable"
@@ -720,7 +721,7 @@ krb5_error_code krb5int_c_copy_keyblock_contents(krb5_context context,
const krb5_keyblock *from,
krb5_keyblock *to);
-krb5_error_code krb5_crypto_us_timeofday(krb5_int32 *, krb5_int32 *);
+krb5_error_code krb5_crypto_us_timeofday(krb5_timestamp *, krb5_int32 *);
/*
* End "los-proto.h"
@@ -1155,7 +1156,10 @@ struct plugin_interface {
#define PLUGIN_INTERFACE_AUDIT 7
#define PLUGIN_INTERFACE_TLS 8
#define PLUGIN_INTERFACE_KDCAUTHDATA 9
-#define PLUGIN_NUM_INTERFACES 10
+#define PLUGIN_INTERFACE_CERTAUTH 10
+#define PLUGIN_INTERFACE_KADM5_AUTH 11
+#define PLUGIN_INTERFACE_KDCPOLICY 12
+#define PLUGIN_NUM_INTERFACES 13
/* Retrieve the plugin module of type interface_id and name modname,
* storing the result into module. */
@@ -1194,7 +1198,7 @@ k5_plugin_free_context(krb5_context context);
struct _kdb5_dal_handle; /* private, in kdb5.h */
typedef struct _kdb5_dal_handle kdb5_dal_handle;
struct _kdb_log_context;
-typedef struct krb5_preauth_context_st krb5_preauth_context;
+typedef struct krb5_preauth_context_st *krb5_preauth_context;
struct ccselect_module_handle;
struct localauth_module_handle;
struct hostrealm_module_handle;
@@ -1231,7 +1235,7 @@ struct _krb5_context {
struct plugin_dir_handle libkrb5_plugins;
/* preauth module stuff */
- krb5_preauth_context *preauth_context;
+ krb5_preauth_context preauth_context;
/* cache module stuff */
struct ccselect_module_handle **ccselect_handles;
@@ -2112,6 +2116,7 @@ krb5_get_tgs_ktypes(krb5_context, krb5_const_principal, krb5_enctype **);
krb5_boolean krb5_is_permitted_enctype(krb5_context, krb5_enctype);
krb5_boolean KRB5_CALLCONV krb5int_c_weak_enctype(krb5_enctype);
+krb5_error_code k5_enctype_to_ssf(krb5_enctype enctype, unsigned int *ssf_out);
krb5_error_code krb5_kdc_rep_decrypt_proc(krb5_context, const krb5_keyblock *,
krb5_const_pointer, krb5_kdc_rep *);
@@ -2350,6 +2355,44 @@ k5memdup0(const void *in, size_t len, krb5_error_code *code)
return ptr;
}
+/* Convert a krb5_timestamp to a time_t value, treating the negative range of
+ * krb5_timestamp as times between 2038 and 2106 (if time_t is 64-bit). */
+static inline time_t
+ts2tt(krb5_timestamp timestamp)
+{
+ return (time_t)(uint32_t)timestamp;
+}
+
+/* Return the delta between two timestamps (a - b) as a signed 32-bit value,
+ * without relying on undefined behavior. */
+static inline krb5_deltat
+ts_delta(krb5_timestamp a, krb5_timestamp b)
+{
+ return (krb5_deltat)((uint32_t)a - (uint32_t)b);
+}
+
+/* Increment a timestamp by a signed 32-bit interval, without relying on
+ * undefined behavior. */
+static inline krb5_timestamp
+ts_incr(krb5_timestamp ts, krb5_deltat delta)
+{
+ return (krb5_timestamp)((uint32_t)ts + (uint32_t)delta);
+}
+
+/* Return true if a comes after b. */
+static inline krb5_boolean
+ts_after(krb5_timestamp a, krb5_timestamp b)
+{
+ return (uint32_t)a > (uint32_t)b;
+}
+
+/* Return true if a and b are within d seconds. */
+static inline krb5_boolean
+ts_within(krb5_timestamp a, krb5_timestamp b, krb5_deltat d)
+{
+ return !ts_after(a, ts_incr(b, d)) && !ts_after(b, ts_incr(a, d));
+}
+
krb5_error_code KRB5_CALLCONV
krb5_get_credentials_for_user(krb5_context context, krb5_flags options,
krb5_ccache ccache,
diff --git a/src/include/k5-platform.h b/src/include/k5-platform.h
index 994f46323cb0..548c0486d567 100644
--- a/src/include/k5-platform.h
+++ b/src/include/k5-platform.h
@@ -71,6 +71,13 @@
#define CAN_COPY_VA_LIST
#endif
+/* This attribute prevents unused function warnings in gcc and clang. */
+#ifdef __GNUC__
+#define UNUSED __attribute__((__unused__))
+#else
+#define UNUSED
+#endif
+
#if defined(macintosh) || (defined(__MACH__) && defined(__APPLE__))
#include <TargetConditionals.h>
#endif
@@ -354,19 +361,7 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
-#if !defined(SHARED) && !defined(_WIN32)
-
-/*
- * In this case, we just don't care about finalization.
- *
- * The code will still define the function, but we won't do anything
- * with it. Annoying: This may generate unused-function warnings.
- */
-
-# define MAKE_FINI_FUNCTION(NAME) \
- static void NAME(void)
-
-#elif defined(USE_LINKER_FINI_OPTION) || defined(_WIN32)
+#if defined(USE_LINKER_FINI_OPTION) || defined(_WIN32)
/* If we're told the linker option will be used, it doesn't really
matter what compiler we're using. Do it the same way
regardless. */
@@ -400,6 +395,15 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
# endif
+#elif !defined(SHARED)
+
+/*
+ * In this case, we just don't care about finalization. The code will still
+ * define the function, but we won't do anything with it.
+ */
+# define MAKE_FINI_FUNCTION(NAME) \
+ static void NAME(void) UNUSED
+
#elif defined(__GNUC__) && defined(DESTRUCTOR_ATTR_WORKS)
/* If we're using gcc, if the C++ support works, the compiler should
build executables and shared libraries that support the use of
@@ -508,7 +512,7 @@ typedef struct { int error; unsigned char did_run; } k5_init_t;
Linux: byteswap.h, bswap_16 etc.
Solaris 10: none
- Mac OS X: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong}
+ macOS: machine/endian.h or byte_order.h, NXSwap{Short,Int,LongLong}
NetBSD: sys/bswap.h, bswap16 etc. */
#if defined(HAVE_BYTESWAP_H) && defined(HAVE_BSWAP_16)
diff --git a/src/include/k5-thread.h b/src/include/k5-thread.h
index 3e3901d6e8fb..a3101239d8a5 100644
--- a/src/include/k5-thread.h
+++ b/src/include/k5-thread.h
@@ -134,6 +134,10 @@
More to be added, perhaps. */
#include <assert.h>
+#ifndef NDEBUG
+#include <stdio.h>
+#include <string.h>
+#endif
/* The mutex structure we use, k5_mutex_t, is defined to some
OS-specific bits. The use of multiple layers of typedefs are an
@@ -363,12 +367,24 @@ static inline int k5_mutex_finish_init(k5_mutex_t *m)
static inline void k5_mutex_lock(k5_mutex_t *m)
{
int r = k5_os_mutex_lock(m);
+#ifndef NDEBUG
+ if (r != 0) {
+ fprintf(stderr, "k5_mutex_lock: Received error %d (%s)\n",
+ r, strerror(r));
+ }
+#endif
assert(r == 0);
}
static inline void k5_mutex_unlock(k5_mutex_t *m)
{
int r = k5_os_mutex_unlock(m);
+#ifndef NDEBUG
+ if (r != 0) {
+ fprintf(stderr, "k5_mutex_unlock: Received error %d (%s)\n",
+ r, strerror(r));
+ }
+#endif
assert(r == 0);
}
diff --git a/src/include/k5-trace.h b/src/include/k5-trace.h
index c75e264e04f2..390a8b7d6fc7 100644
--- a/src/include/k5-trace.h
+++ b/src/include/k5-trace.h
@@ -155,6 +155,20 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "ccselect choosing default cache {ccache} for server " \
"principal {princ}", cache, server)
+#define TRACE_DNS_SRV_ANS(c, host, port, prio, weight) \
+ TRACE(c, "SRV answer: {int} {int} {int} \"{str}\"", prio, weight, \
+ port, host)
+#define TRACE_DNS_SRV_NOTFOUND(c) \
+ TRACE(c, "No SRV records found")
+#define TRACE_DNS_SRV_SEND(c, domain) \
+ TRACE(c, "Sending DNS SRV query for {str}", domain)
+#define TRACE_DNS_URI_ANS(c, uri, prio, weight) \
+ TRACE(c, "URI answer: {int} {int} \"{str}\"", prio, weight, uri)
+#define TRACE_DNS_URI_NOTFOUND(c) \
+ TRACE(c, "No URI records found")
+#define TRACE_DNS_URI_SEND(c, domain) \
+ TRACE(c, "Sending DNS URI query for {str}", domain)
+
#define TRACE_FAST_ARMOR_CCACHE(c, ccache_name) \
TRACE(c, "FAST armor ccache: {str}", ccache_name)
#define TRACE_FAST_ARMOR_CCACHE_KEY(c, keyblock) \
@@ -213,8 +227,19 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
TRACE(c, "Looked up etypes in keytab: {etypes}", etypes)
#define TRACE_INIT_CREDS_KEYTAB_LOOKUP_FAILED(c, code) \
TRACE(c, "Couldn't lookup etypes in keytab: {kerr}", code)
+#define TRACE_INIT_CREDS_PREAUTH(c) \
+ TRACE(c, "Preauthenticating using KDC method data")
#define TRACE_INIT_CREDS_PREAUTH_DECRYPT_FAIL(c, code) \
TRACE(c, "Decrypt with preauth AS key failed: {kerr}", code)
+#define TRACE_INIT_CREDS_PREAUTH_MORE(c, patype) \
+ TRACE(c, "Continuing preauth mech {int}", (int)patype)
+#define TRACE_INIT_CREDS_PREAUTH_NONE(c) \
+ TRACE(c, "Sending unauthenticated request")
+#define TRACE_INIT_CREDS_PREAUTH_OPTIMISTIC(c) \
+ TRACE(c, "Attempting optimistic preauth")
+#define TRACE_INIT_CREDS_PREAUTH_TRYAGAIN(c, patype, code) \
+ TRACE(c, "Recovering from KDC error {int} using preauth mech {int}", \
+ (int)patype, (int)code)
#define TRACE_INIT_CREDS_RESTART_FAST(c) \
TRACE(c, "Restarting to upgrade to FAST")
#define TRACE_INIT_CREDS_RESTART_PREAUTH_FAILED(c) \
@@ -228,6 +253,13 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_INIT_CREDS_SERVICE(c, service) \
TRACE(c, "Setting initial creds service to {str}", service)
+#define TRACE_KADM5_AUTH_VTINIT_FAIL(c, ret) \
+ TRACE(c, "kadm5_auth module failed to init vtable: {kerr}", ret)
+#define TRACE_KADM5_AUTH_INIT_FAIL(c, name, ret) \
+ TRACE(c, "kadm5_auth module {str} failed to init: {kerr}", ret)
+#define TRACE_KADM5_AUTH_INIT_SKIP(c, name) \
+ TRACE(c, "kadm5_auth module {str} declined to initialize", name)
+
#define TRACE_KT_GET_ENTRY(c, keytab, princ, vno, enctype, err) \
TRACE(c, "Retrieving {princ} from {keytab} (vno {int}, enctype {etype}) " \
"with result: {kerr}", princ, keytab, (int) vno, enctype, err)
@@ -287,10 +319,16 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_PREAUTH_SKIP(c, name, patype) \
TRACE(c, "Skipping previously used preauth module {str} ({int})", \
name, (int) patype)
-#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, padata) \
- TRACE(c, "Preauth tryagain input types: {patypes}", padata)
+#define TRACE_PREAUTH_TRYAGAIN_INPUT(c, patype, padata) \
+ TRACE(c, "Preauth tryagain input types ({int}): {patypes}", patype, padata)
+#define TRACE_PREAUTH_TRYAGAIN(c, name, patype, code) \
+ TRACE(c, "Preauth module {str} ({int}) tryagain returned: {kerr}", \
+ name, (int)patype, code)
#define TRACE_PREAUTH_TRYAGAIN_OUTPUT(c, padata) \
TRACE(c, "Followup preauth for next request: {patypes}", padata)
+#define TRACE_PREAUTH_WRONG_CONTEXT(c) \
+ TRACE(c, "Wrong context passed to krb5_init_creds_free(); leaking " \
+ "modreq objects")
#define TRACE_PROFILE_ERR(c,subsection, section, retval) \
TRACE(c, "Bad value of {str} from [{str}] in conf file: {kerr}", \
@@ -454,4 +492,9 @@ void krb5int_trace(krb5_context context, const char *fmt, ...);
#define TRACE_GET_CRED_VIA_TKT_EXT_RETURN(c, ret) \
TRACE(c, "Got cred; {kerr}", ret)
+#define TRACE_KDCPOLICY_VTINIT_FAIL(c, ret) \
+ TRACE(c, "KDC policy module failed to init vtable: {kerr}", ret)
+#define TRACE_KDCPOLICY_INIT_SKIP(c, name) \
+ TRACE(c, "kadm5_auth module {str} declined to initialize", name)
+
#endif /* K5_TRACE_H */
diff --git a/src/include/k5-utf8.h b/src/include/k5-utf8.h
index 22f433c8e981..e2f20d45028f 100644
--- a/src/include/k5-utf8.h
+++ b/src/include/k5-utf8.h
@@ -73,57 +73,28 @@
typedef uint16_t krb5_ucs2;
typedef uint32_t krb5_ucs4;
-#define KRB5_MAX_UTF8_LEN (sizeof(krb5_ucs2) * 3/2)
-
int krb5int_utf8_to_ucs2(const char *p, krb5_ucs2 *out);
size_t krb5int_ucs2_to_utf8(krb5_ucs2 c, char *buf);
int krb5int_utf8_to_ucs4(const char *p, krb5_ucs4 *out);
size_t krb5int_ucs4_to_utf8(krb5_ucs4 c, char *buf);
-int
-krb5int_ucs2s_to_utf8s(const krb5_ucs2 *ucs2s,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2cs_to_utf8s(const krb5_ucs2 *ucs2s,
- size_t ucs2slen,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2les_to_utf8s(const unsigned char *ucs2les,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_ucs2lecs_to_utf8s(const unsigned char *ucs2les,
- size_t ucs2leslen,
- char **utf8s,
- size_t *utf8slen);
-
-int
-krb5int_utf8s_to_ucs2s(const char *utf8s,
- krb5_ucs2 **ucs2s,
- size_t *ucs2chars);
-
-int
-krb5int_utf8cs_to_ucs2s(const char *utf8s,
- size_t utf8slen,
- krb5_ucs2 **ucs2s,
- size_t *ucs2chars);
-
-int
-krb5int_utf8s_to_ucs2les(const char *utf8s,
- unsigned char **ucs2les,
- size_t *ucs2leslen);
-
-int
-krb5int_utf8cs_to_ucs2les(const char *utf8s,
- size_t utf8slen,
- unsigned char **ucs2les,
- size_t *ucs2leslen);
+/*
+ * Convert a little-endian UTF-16 string to an allocated null-terminated UTF-8
+ * string. nbytes is the length of ucs2bytes in bytes, and must be an even
+ * number. Return EINVAL on invalid input, ENOMEM on out of memory, or 0 on
+ * success.
+ */
+int k5_utf16le_to_utf8(const uint8_t *utf16bytes, size_t nbytes,
+ char **utf8_out);
+
+/*
+ * Convert a UTF-8 string to an allocated little-endian UTF-16 string. The
+ * resulting length is in bytes and will always be even. Return EINVAL on
+ * invalid input, ENOMEM on out of memory, or 0 on success.
+ */
+int k5_utf8_to_utf16le(const char *utf8, uint8_t **utf16_out,
+ size_t *nbytes_out);
/* returns the number of bytes in the UTF-8 string */
size_t krb5int_utf8_bytes(const char *);
diff --git a/src/include/kdb.h b/src/include/kdb.h
index da04724fcedb..5615329c0bb3 100644
--- a/src/include/kdb.h
+++ b/src/include/kdb.h
@@ -69,7 +69,7 @@
/* This version will be incremented when incompatible changes are made to the
* KDB API, and will be kept in sync with the libkdb major version. */
-#define KRB5_KDB_API_VERSION 8
+#define KRB5_KDB_API_VERSION 9
/* Salt types */
#define KRB5_KDB_SALTTYPE_NORMAL 0
@@ -695,6 +695,8 @@ krb5_error_code krb5_db_check_policy_tgs(krb5_context kcontext,
krb5_pa_data ***e_data);
void krb5_db_audit_as_req(krb5_context kcontext, krb5_kdc_req *request,
+ const krb5_address *local_addr,
+ const krb5_address *remote_addr,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp authtime, krb5_error_code error_code);
@@ -865,7 +867,7 @@ krb5_error_code krb5_db_register_keytab(krb5_context context);
* This number indicates the date of the last incompatible change to the DAL.
* The maj_ver field of the module's vtable structure must match this version.
*/
-#define KRB5_KDB_DAL_MAJOR_VERSION 6
+#define KRB5_KDB_DAL_MAJOR_VERSION 7
/*
* A krb5_context can hold one database object. Modules should use
@@ -1356,6 +1358,8 @@ typedef struct _kdb_vftabl {
* AS request.
*/
void (*audit_as_req)(krb5_context kcontext, krb5_kdc_req *request,
+ const krb5_address *local_addr,
+ const krb5_address *remote_addr,
krb5_db_entry *client, krb5_db_entry *server,
krb5_timestamp authtime, krb5_error_code error_code);
diff --git a/src/include/kdb_log.h b/src/include/kdb_log.h
index 25b823674a9f..4239575659a3 100644
--- a/src/include/kdb_log.h
+++ b/src/include/kdb_log.h
@@ -21,9 +21,8 @@ extern "C" {
/*
* DB macros
*/
-#define INDEX(ulog, i) (kdb_ent_header_t *)((char *)(ulog) + \
- sizeof(kdb_hlog_t) + \
- (i) * ulog->kdb_block)
+#define INDEX(ulog, i) (kdb_ent_header_t *)(void *) \
+ ((char *)(ulog) + sizeof(kdb_hlog_t) + (i) * ulog->kdb_block)
/*
* Current DB version #
diff --git a/src/include/krb5/certauth_plugin.h b/src/include/krb5/certauth_plugin.h
new file mode 100644
index 000000000000..3074790f8745
--- /dev/null
+++ b/src/include/krb5/certauth_plugin.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/certauth_plugin.h - certauth plugin header. */
+/*
+ * Copyright (C) 2017 by Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Declarations for certauth plugin module implementors.
+ *
+ * The certauth pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * certauth plugin modules should define a function named
+ * certauth_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * certauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_certauth_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_CERTAUTH_PLUGIN_H
+#define KRB5_CERTAUTH_PLUGIN_H
+
+#include <krb5/krb5.h>
+#include <krb5/plugin.h>
+
+/* Abstract module data type. */
+typedef struct krb5_certauth_moddata_st *krb5_certauth_moddata;
+
+/* A module can optionally include <kdb.h> to inspect the client principal
+ * entry when authorizing a request. */
+struct _krb5_db_entry_new;
+
+/*
+ * Optional: Initialize module data.
+ */
+typedef krb5_error_code
+(*krb5_certauth_init_fn)(krb5_context context,
+ krb5_certauth_moddata *moddata_out);
+
+/*
+ * Optional: Clean up the module data.
+ */
+typedef void
+(*krb5_certauth_fini_fn)(krb5_context context, krb5_certauth_moddata moddata);
+
+/*
+ * Mandatory:
+ * Return 0 if the DER-encoded cert is authorized for PKINIT authentication by
+ * princ; otherwise return one of the following error codes:
+ * - KRB5KDC_ERR_CLIENT_NAME_MISMATCH - incorrect SAN value
+ * - KRB5KDC_ERR_INCONSISTENT_KEY_PURPOSE - incorrect EKU
+ * - KRB5KDC_ERR_CERTIFICATE_MISMATCH - other extension error
+ * - KRB5_PLUGIN_NO_HANDLE - the module has no opinion about cert
+ *
+ * - opts is used by built-in modules to receive internal data, and must be
+ * ignored by other modules.
+ * - db_entry receives the client principal database entry, and can be ignored
+ * by modules that do not link with libkdb5.
+ * - *authinds_out optionally returns a null-terminated list of authentication
+ * indicator strings upon KRB5_PLUGIN_NO_HANDLE or accepted authorization.
+ */
+typedef krb5_error_code
+(*krb5_certauth_authorize_fn)(krb5_context context,
+ krb5_certauth_moddata moddata,
+ const uint8_t *cert, size_t cert_len,
+ krb5_const_principal princ, const void *opts,
+ const struct _krb5_db_entry_new *db_entry,
+ char ***authinds_out);
+
+/*
+ * Free indicators allocated by a module. Mandatory if authorize returns
+ * authentication indicators.
+ */
+typedef void
+(*krb5_certauth_free_indicator_fn)(krb5_context context,
+ krb5_certauth_moddata moddata,
+ char **authinds);
+
+typedef struct krb5_certauth_vtable_st {
+ const char *name;
+ krb5_certauth_init_fn init;
+ krb5_certauth_fini_fn fini;
+ krb5_certauth_authorize_fn authorize;
+ krb5_certauth_free_indicator_fn free_ind;
+} *krb5_certauth_vtable;
+
+#endif /* KRB5_CERTAUTH_PLUGIN_H */
diff --git a/src/include/krb5/kadm5_auth_plugin.h b/src/include/krb5/kadm5_auth_plugin.h
new file mode 100644
index 000000000000..d514e99beb93
--- /dev/null
+++ b/src/include/krb5/kadm5_auth_plugin.h
@@ -0,0 +1,306 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/*
+ * Copyright (C) 2017 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Declarations for kadm5_auth plugin module implementors.
+ *
+ * The kadm5_auth pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * kadm5_auth plugin modules should define a function named
+ * kadm5_auth_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * kadm5_auth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_kadm5_auth_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_KADM5_AUTH_PLUGIN_H
+#define KRB5_KADM5_AUTH_PLUGIN_H
+
+#include <krb5/krb5.h>
+#include <krb5/plugin.h>
+
+/* An abstract type for kadm5_auth module data. */
+typedef struct kadm5_auth_moddata_st *kadm5_auth_moddata;
+
+/*
+ * A module can optionally include <kadm5/admin.h> to inspect principal or
+ * policy records from requests that add or modify principals or policies.
+ * Note that fields of principal and policy structures are only valid if the
+ * corresponding bit is set in the accompanying mask parameter.
+ */
+struct _kadm5_principal_ent_t;
+struct _kadm5_policy_ent_t;
+
+/*
+ * A module can optionally generate restrictions when checking permissions for
+ * adding or modifying a principal entry. Restriction fields will only be
+ * honored if the corresponding mask bit is set. The operable mask bits are
+ * defined in <kadmin/admin.h> and are:
+ *
+ * - KADM5_ATTRIBUTES for require_attrs, forbid_attrs
+ * - KADM5_POLICY for policy
+ * - KADM5_POLICY_CLR to require that policy be unset
+ * - KADM5_PRINC_EXPIRE_TIME for princ_lifetime
+ * - KADM5_PW_EXPIRATION for pw_lifetime
+ * - KADM5_MAX_LIFE for max_life
+ * - KADM5_MAX_RLIFE for max_renewable_life
+ */
+struct kadm5_auth_restrictions {
+ long mask;
+ krb5_flags require_attrs;
+ krb5_flags forbid_attrs;
+ krb5_deltat princ_lifetime;
+ krb5_deltat pw_lifetime;
+ krb5_deltat max_life;
+ krb5_deltat max_renewable_life;
+ char *policy;
+};
+
+/*** Method type declarations ***/
+
+/*
+ * Optional: Initialize module data. acl_file is the realm's configured ACL
+ * file, or NULL if none was configured. Return 0 on success,
+ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for
+ * example), and any other error code to abort kadmind startup. Optionally set
+ * *data_out to a module data object to be passed to future calls.
+ */
+typedef krb5_error_code
+(*kadm5_auth_init_fn)(krb5_context context, const char *acl_file,
+ kadm5_auth_moddata *data_out);
+
+/* Optional: Release resources used by module data. */
+typedef void
+(*kadm5_auth_fini_fn)(krb5_context context, kadm5_auth_moddata data);
+
+/*
+ * Each check method below should return 0 to explicitly authorize the request,
+ * KRB5_PLUGIN_NO_HANDLE to neither authorize nor deny the request, and any
+ * other error code (such as EPERM) to explicitly deny the request. If a check
+ * method is not defined, the module will neither authorize nor deny the
+ * request. A request succeeds if at least one kadm5_auth module explicitly
+ * authorizes the request and none of the modules explicitly deny it.
+ */
+
+/* Optional: authorize an add-principal operation, and optionally generate
+ * restrictions. */
+typedef krb5_error_code
+(*kadm5_auth_addprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out);
+
+/* Optional: authorize a modify-principal operation, and optionally generate
+ * restrictions. */
+typedef krb5_error_code
+(*kadm5_auth_modprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const struct _kadm5_principal_ent_t *ent, long mask,
+ struct kadm5_auth_restrictions **rs_out);
+
+/* Optional: authorize a set-string operation. */
+typedef krb5_error_code
+(*kadm5_auth_setstr_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target,
+ const char *key, const char *value);
+
+/* Optional: authorize a change-password operation. */
+typedef krb5_error_code
+(*kadm5_auth_cpw_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, krb5_const_principal target);
+
+/* Optional: authorize a randomize-keys operation. */
+typedef krb5_error_code
+(*kadm5_auth_chrand_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a set-key operation. */
+typedef krb5_error_code
+(*kadm5_auth_setkey_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a purgekeys operation. */
+typedef krb5_error_code
+(*kadm5_auth_purgekeys_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a delete-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_delprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a rename-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_renprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal src,
+ krb5_const_principal dest);
+
+/* Optional: authorize a get-principal operation. */
+typedef krb5_error_code
+(*kadm5_auth_getprinc_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a get-strings operation. */
+typedef krb5_error_code
+(*kadm5_auth_getstrs_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize an extract-keys operation. */
+typedef krb5_error_code
+(*kadm5_auth_extract_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client,
+ krb5_const_principal target);
+
+/* Optional: authorize a list-principals operation. */
+typedef krb5_error_code
+(*kadm5_auth_listprincs_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/* Optional: authorize an add-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_addpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask);
+
+/* Optional: authorize a modify-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_modpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const struct _kadm5_policy_ent_t *ent, long mask);
+
+/* Optional: authorize a delete-policy operation. */
+typedef krb5_error_code
+(*kadm5_auth_delpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy);
+
+/* Optional: authorize a get-policy operation. client_policy is the client
+ * principal's policy name, or NULL if it does not have one. */
+typedef krb5_error_code
+(*kadm5_auth_getpol_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client, const char *policy,
+ const char *client_policy);
+
+/* Optional: authorize a list-policies operation. */
+typedef krb5_error_code
+(*kadm5_auth_listpols_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/* Optional: authorize an iprop operation. */
+typedef krb5_error_code
+(*kadm5_auth_iprop_fn)(krb5_context context, kadm5_auth_moddata data,
+ krb5_const_principal client);
+
+/*
+ * Optional: receive a notification that the most recent authorized operation
+ * has ended. If a kadm5_auth module is also a KDB module, it can assume that
+ * all KDB methods invoked between a kadm5_auth authorization method invocation
+ * and a kadm5_auth end invocation are performed as part of the authorized
+ * operation.
+ *
+ * The end method may be invoked without a preceding authorization method in
+ * some cases; the module must be prepared to ignore such calls.
+ */
+typedef void
+(*kadm5_auth_end_fn)(krb5_context context, kadm5_auth_moddata data);
+
+/*
+ * Optional: free a restrictions object. This method does not need to be
+ * defined if the module does not generate restrictions objects, or if it
+ * returns aliases to restrictions objects contained from within the module
+ * data.
+ */
+typedef void
+(*kadm5_auth_free_restrictions_fn)(krb5_context context,
+ kadm5_auth_moddata data,
+ struct kadm5_auth_restrictions *rs);
+
+/* kadm5_auth vtable for major version 1. */
+typedef struct kadm5_auth_vtable_st {
+ const char *name; /* Mandatory: name of module. */
+ kadm5_auth_init_fn init;
+ kadm5_auth_fini_fn fini;
+
+ kadm5_auth_addprinc_fn addprinc;
+ kadm5_auth_modprinc_fn modprinc;
+ kadm5_auth_setstr_fn setstr;
+ kadm5_auth_cpw_fn cpw;
+ kadm5_auth_chrand_fn chrand;
+ kadm5_auth_setkey_fn setkey;
+ kadm5_auth_purgekeys_fn purgekeys;
+ kadm5_auth_delprinc_fn delprinc;
+ kadm5_auth_renprinc_fn renprinc;
+
+ kadm5_auth_getprinc_fn getprinc;
+ kadm5_auth_getstrs_fn getstrs;
+ kadm5_auth_extract_fn extract;
+ kadm5_auth_listprincs_fn listprincs;
+
+ kadm5_auth_addpol_fn addpol;
+ kadm5_auth_modpol_fn modpol;
+ kadm5_auth_delpol_fn delpol;
+ kadm5_auth_getpol_fn getpol;
+ kadm5_auth_listpols_fn listpols;
+
+ kadm5_auth_iprop_fn iprop;
+
+ kadm5_auth_end_fn end;
+
+ kadm5_auth_free_restrictions_fn free_restrictions;
+ /* Minor version 1 ends here. */
+} *kadm5_auth_vtable;
+
+#endif /* KRB5_KADM5_AUTH_PLUGIN_H */
diff --git a/src/include/krb5/kdcpolicy_plugin.h b/src/include/krb5/kdcpolicy_plugin.h
new file mode 100644
index 000000000000..c7592c5dba78
--- /dev/null
+++ b/src/include/krb5/kdcpolicy_plugin.h
@@ -0,0 +1,128 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/krb5/kdcpolicy_plugin.h - KDC policy plugin interface */
+/*
+ * Copyright (C) 2017 by Red Hat, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Declarations for kdcpolicy plugin module implementors.
+ *
+ * The kdcpolicy pluggable interface currently has only one supported major
+ * version, which is 1. Major version 1 has a current minor version number of
+ * 1.
+ *
+ * kdcpolicy plugin modules should define a function named
+ * kdcpolicy_<modulename>_initvt, matching the signature:
+ *
+ * krb5_error_code
+ * kdcpolicy_modname_initvt(krb5_context context, int maj_ver, int min_ver,
+ * krb5_plugin_vtable vtable);
+ *
+ * The initvt function should:
+ *
+ * - Check that the supplied maj_ver number is supported by the module, or
+ * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
+ *
+ * - Cast the vtable pointer as appropriate for maj_ver:
+ * maj_ver == 1: Cast to krb5_kdcpolicy_vtable
+ *
+ * - Initialize the methods of the vtable, stopping as appropriate for the
+ * supplied min_ver. Optional methods may be left uninitialized.
+ *
+ * Memory for the vtable is allocated by the caller, not by the module.
+ */
+
+#ifndef KRB5_POLICY_PLUGIN_H
+#define KRB5_POLICY_PLUGIN_H
+
+#include <krb5/krb5.h>
+
+/* Abstract module datatype. */
+typedef struct krb5_kdcpolicy_moddata_st *krb5_kdcpolicy_moddata;
+
+/* A module can optionally include kdb.h to inspect principal entries when
+ * authorizing requests. */
+struct _krb5_db_entry_new;
+
+/*
+ * Optional: Initialize module data. Return 0 on success,
+ * KRB5_PLUGIN_NO_HANDLE if the module is inoperable (due to configuration, for
+ * example), and any other error code to abort KDC startup. Optionally set
+ * *data_out to a module data object to be passed to future calls.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_init_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata *data_out);
+
+/* Optional: Clean up module data. */
+typedef krb5_error_code
+(*krb5_kdcpolicy_fini_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny an AS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_as_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *client,
+ const struct _krb5_db_entry_new *server,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+/*
+ * Optional: return an error code and set status to an appropriate string
+ * literal to deny a TGS request; otherwise return 0. lifetime_out, if set,
+ * restricts the ticket lifetime. renew_lifetime_out, if set, restricts the
+ * ticket renewable lifetime.
+ */
+typedef krb5_error_code
+(*krb5_kdcpolicy_check_tgs_fn)(krb5_context context,
+ krb5_kdcpolicy_moddata moddata,
+ const krb5_kdc_req *request,
+ const struct _krb5_db_entry_new *server,
+ const krb5_ticket *ticket,
+ const char *const *auth_indicators,
+ const char **status, krb5_deltat *lifetime_out,
+ krb5_deltat *renew_lifetime_out);
+
+typedef struct krb5_kdcpolicy_vtable_st {
+ const char *name;
+ krb5_kdcpolicy_init_fn init;
+ krb5_kdcpolicy_fini_fn fini;
+ krb5_kdcpolicy_check_as_fn check_as;
+ krb5_kdcpolicy_check_tgs_fn check_tgs;
+} *krb5_kdcpolicy_vtable;
+
+#endif /* KRB5_POLICY_PLUGIN_H */
diff --git a/src/include/krb5/kdcpreauth_plugin.h b/src/include/krb5/kdcpreauth_plugin.h
index f455effaecdb..f388200999ef 100644
--- a/src/include/krb5/kdcpreauth_plugin.h
+++ b/src/include/krb5/kdcpreauth_plugin.h
@@ -34,7 +34,7 @@
* Declarations for kdcpreauth plugin module implementors.
*
* The kdcpreauth interface has a single supported major version, which is 1.
- * Major version 1 has a current minor version of 3. kdcpreauth modules should
+ * Major version 1 has a current minor version of 2. kdcpreauth modules should
* define a function named kdcpreauth_<modulename>_initvt, matching the
* signature:
*
@@ -221,6 +221,25 @@ typedef struct krb5_kdcpreauth_callbacks_st {
/* End of version 3 kdcpreauth callbacks. */
+ /*
+ * Return true if princ matches the principal named in the request or the
+ * client principal (possibly canonicalized). If princ does not match,
+ * attempt a database lookup of princ with aliases allowed and compare the
+ * result to the client principal, returning true if it matches.
+ * Otherwise, return false.
+ */
+ krb5_boolean (*match_client)(krb5_context context,
+ krb5_kdcpreauth_rock rock,
+ krb5_principal princ);
+
+ /*
+ * Get an alias to the client DB entry principal (possibly canonicalized).
+ */
+ krb5_principal (*client_name)(krb5_context context,
+ krb5_kdcpreauth_rock rock);
+
+ /* End of version 4 kdcpreauth callbacks. */
+
} *krb5_kdcpreauth_callbacks;
/* Optional: preauth plugin initialization function. */
diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin
index ac22f4c55098..c86e78274484 100644
--- a/src/include/krb5/krb5.hin
+++ b/src/include/krb5/krb5.hin
@@ -181,7 +181,16 @@ typedef krb5_int32 krb5_cryptotype;
typedef krb5_int32 krb5_preauthtype; /* This may change, later on */
typedef krb5_int32 krb5_flags;
+
+/**
+ * Represents a timestamp in seconds since the POSIX epoch. This legacy type
+ * is used frequently in the ABI, but cannot represent timestamps after 2038 as
+ * a positive number. Code which uses this type should cast values of it to
+ * uint32_t so that negative values are treated as timestamps between 2038 and
+ * 2106 on platforms with 64-bit time_t.
+ */
typedef krb5_int32 krb5_timestamp;
+
typedef krb5_int32 krb5_deltat;
/**
@@ -3221,8 +3230,9 @@ krb5_get_credentials_renew(krb5_context context, krb5_flags options,
*/
krb5_error_code KRB5_CALLCONV
krb5_mk_req(krb5_context context, krb5_auth_context *auth_context,
- krb5_flags ap_req_options, char *service, char *hostname,
- krb5_data *in_data, krb5_ccache ccache, krb5_data *outbuf);
+ krb5_flags ap_req_options, const char *service,
+ const char *hostname, krb5_data *in_data, krb5_ccache ccache,
+ krb5_data *outbuf);
/**
* Create a @c KRB_AP_REQ message using supplied credentials.
@@ -5615,8 +5625,9 @@ krb5_rd_cred(krb5_context context, krb5_auth_context auth_context,
*/
krb5_error_code KRB5_CALLCONV
krb5_fwd_tgt_creds(krb5_context context, krb5_auth_context auth_context,
- char *rhost, krb5_principal client, krb5_principal server,
- krb5_ccache cc, int forwardable, krb5_data *outbuf);
+ const char *rhost, krb5_principal client,
+ krb5_principal server, krb5_ccache cc, int forwardable,
+ krb5_data *outbuf);
/**
* Create and initialize an authentication context.
@@ -6000,15 +6011,19 @@ krb5_error_code KRB5_CALLCONV
krb5_auth_con_getremoteseqnumber(krb5_context context, krb5_auth_context auth_context,
krb5_int32 *seqnumber);
-#if KRB5_DEPRECATED
-/** @deprecated Not replaced.
+/**
+ * Cause an auth context to use cipher state.
+ *
+ * @param [in] context Library context
+ * @param [in] auth_context Authentication context
*
- * RFC 4120 doesn't have anything like the initvector concept;
- * only really old protocols may need this API.
+ * Prepare @a auth_context to use cipher state when krb5_mk_priv() or
+ * krb5_rd_priv() encrypt or decrypt data.
+ *
+ * @retval 0 Success; otherwise - Kerberos error codes
*/
-KRB5_ATTR_DEPRECATED krb5_error_code KRB5_CALLCONV
+krb5_error_code KRB5_CALLCONV
krb5_auth_con_initivector(krb5_context context, krb5_auth_context auth_context);
-#endif
/**
* Set the replay cache in an auth context.
@@ -7306,6 +7321,9 @@ typedef struct _krb5_init_creds_context *krb5_init_creds_context;
*
* @param [in] context Library context
* @param [in] ctx Initial credentials context
+ *
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
*/
void KRB5_CALLCONV
krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
@@ -7320,6 +7338,9 @@ krb5_init_creds_free(krb5_context context, krb5_init_creds_context ctx);
* krb5_init_creds_init(). On successful return, the credentials can be
* retrieved with krb5_init_creds_get_creds().
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7370,6 +7391,10 @@ krb5_init_creds_get_error(krb5_context context, krb5_init_creds_context ctx,
* This function creates a new context for acquiring initial credentials. Use
* krb5_init_creds_free() to free @a ctx when it is no longer needed.
*
+ * Any subsequent calls to krb5_init_creds_step(), krb5_init_creds_get(), or
+ * krb5_init_creds_free() for this initial credentials context must use the
+ * same @a context argument as the one passed to this function.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -7419,6 +7444,9 @@ krb5_init_creds_set_keytab(krb5_context context, krb5_init_creds_context ctx,
* transmit the next request using TCP rather than UDP. If this function
* returns any other error, the initial credential exchange has failed.
*
+ * @a context must be the same as the one passed to krb5_init_creds_init() for
+ * this initial credentials context.
+ *
* @retval 0 Success; otherwise - Kerberos error codes
*/
krb5_error_code KRB5_CALLCONV
@@ -8229,9 +8257,9 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len,
* If successful, @a pac is marked as verified.
*
* @note A checksum mismatch can occur if the PAC was copied from a cross-realm
- * TGT by an ignorant KDC; also Apple Mac OS X Server Open Directory (as of
- * 10.6) generates PACs with no server checksum at all. One should consider
- * not failing the whole authentication because of this reason, but, instead,
+ * TGT by an ignorant KDC; also macOS Server Open Directory (as of 10.6)
+ * generates PACs with no server checksum at all. One should consider not
+ * failing the whole authentication because of this reason, but, instead,
* treating the ticket as if it did not contain a PAC or marking the PAC
* information as non-verified.
*
diff --git a/src/include/net-server.h b/src/include/net-server.h
index 37721e7f17a0..e5edcc49d5a1 100644
--- a/src/include/net-server.h
+++ b/src/include/net-server.h
@@ -86,7 +86,7 @@ void loop_free(verto_ctx *ctx);
*/
typedef void (*loop_respond_fn)(void *arg, krb5_error_code code,
krb5_data *response);
-void dispatch(void *handle, struct sockaddr *local_addr,
+void dispatch(void *handle, const krb5_fulladdr *local_addr,
const krb5_fulladdr *remote_addr, krb5_data *request,
int is_tcp, verto_ctx *vctx, loop_respond_fn respond, void *arg);
krb5_error_code make_toolong_error (void *handle, krb5_data **);
diff --git a/src/include/socket-utils.h b/src/include/socket-utils.h
index 156663683047..e1f33aa31763 100644
--- a/src/include/socket-utils.h
+++ b/src/include/socket-utils.h
@@ -119,6 +119,17 @@ sa_is_inet(struct sockaddr *sa)
return sa->sa_family == AF_INET || sa->sa_family == AF_INET6;
}
+/* Return true if sa is an IPv4 or IPv6 wildcard address. */
+static inline int
+sa_is_wildcard(struct sockaddr *sa)
+{
+ if (sa->sa_family == AF_INET6)
+ return IN6_IS_ADDR_UNSPECIFIED(&sa2sin6(sa)->sin6_addr);
+ else if (sa->sa_family == AF_INET)
+ return sa2sin(sa)->sin_addr.s_addr == INADDR_ANY;
+ return 0;
+}
+
/* Return the length of an IPv4 or IPv6 socket structure; abort if it is
* neither. */
static inline socklen_t
diff --git a/src/include/win-mac.h b/src/include/win-mac.h
index 1994388b71d3..c3744ed14ee6 100644
--- a/src/include/win-mac.h
+++ b/src/include/win-mac.h
@@ -225,9 +225,7 @@ typedef _W64 int ssize_t;
HINSTANCE get_lib_instance(void);
-#define GETSOCKNAME_ARG2_TYPE struct sockaddr
#define GETSOCKNAME_ARG3_TYPE size_t
-#define GETPEERNAME_ARG2_TYPE GETSOCKNAME_ARG2_TYPE
#define GETPEERNAME_ARG3_TYPE GETSOCKNAME_ARG3_TYPE
#endif /* !RES_ONLY */