2 * Portability wrapper around krb5.h.
4 * This header includes krb5.h and then adjusts for various portability
5 * issues, primarily between MIT Kerberos and Heimdal, so that code can be
6 * written to a consistent API.
8 * Unfortunately, due to the nature of the differences between MIT Kerberos
9 * and Heimdal, it's not possible to write code to either one of the APIs and
10 * adjust for the other one. In general, this header tries to make available
11 * the Heimdal API and fix it for MIT Kerberos, but there are places where MIT
12 * Kerberos requires a more specific call. For those cases, it provides the
13 * most specific interface.
15 * For example, MIT Kerberos has krb5_free_unparsed_name() whereas Heimdal
16 * prefers the generic krb5_xfree(). In this case, this header provides
17 * krb5_free_unparsed_name() for both APIs since it's the most specific call.
19 * The canonical version of this file is maintained in the rra-c-util package,
20 * which can be found at <https://www.eyrie.org/~eagle/software/rra-c-util/>.
22 * Written by Russ Allbery <eagle@eyrie.org>
24 * The authors hereby relinquish any claim to any copyright that they may have
25 * in this work, whether granted under contract or by operation of law or
26 * international treaty, and hereby commit to the public, at large, that they
27 * shall not, at any time in the future, seek to enforce any copyright in this
28 * work against any person or entity, or prevent any person or entity from
29 * copying, publishing, distributing or creating derivative works of this
33 #ifndef PORTABLE_KRB5_H
34 #define PORTABLE_KRB5_H 1
37 * Allow inclusion of config.h to be skipped, since sometimes we have to use a
38 * stripped-down version of config.h with a different name.
40 #ifndef CONFIG_H_INCLUDED
43 #include <portable/macros.h>
45 #if defined(HAVE_KRB5_H)
47 #elif defined(HAVE_KERBEROSV5_KRB5_H)
48 # include <kerberosv5/krb5.h>
50 # include <krb5/krb5.h>
56 /* Default to a hidden visibility for all portability functions. */
57 #pragma GCC visibility push(hidden)
60 * MIT-specific. The Heimdal documentation says to use free(), but that
61 * doesn't actually make sense since the memory is allocated inside the
62 * Kerberos library. Use krb5_xfree instead.
64 #ifndef HAVE_KRB5_FREE_DEFAULT_REALM
65 # define krb5_free_default_realm(c, r) krb5_xfree(r)
69 * Heimdal: krb5_xfree, MIT: krb5_free_string, older MIT uses free(). Note
70 * that we can incorrectly allocate in the library and call free() if
71 * krb5_free_string is not available but something we use that API for is
72 * available, such as krb5_appdefaults_*, but there isn't anything we can
75 #ifndef HAVE_KRB5_FREE_STRING
76 # ifdef HAVE_KRB5_XFREE
77 # define krb5_free_string(c, s) krb5_xfree(s)
79 # define krb5_free_string(c, s) free(s)
83 /* Heimdal: krb5_xfree, MIT: krb5_free_unparsed_name. */
84 #ifdef HAVE_KRB5_XFREE
85 # define krb5_free_unparsed_name(c, p) krb5_xfree(p)
89 * krb5_{get,free}_error_message are the preferred APIs for both current MIT
90 * and current Heimdal, but there are tons of older APIs we may have to fall
91 * back on for earlier versions.
93 * This function should be called immediately after the corresponding error
94 * without any intervening Kerberos calls. Otherwise, the correct error
95 * message and supporting information may not be returned.
97 #ifndef HAVE_KRB5_GET_ERROR_MESSAGE
98 const char *krb5_get_error_message(krb5_context, krb5_error_code);
100 #ifndef HAVE_KRB5_FREE_ERROR_MESSAGE
101 void krb5_free_error_message(krb5_context, const char *);
105 * Both current MIT and current Heimdal prefer _opt_alloc and _opt_free, but
106 * older versions of both require allocating your own struct and calling
109 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC
110 krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context,
111 krb5_get_init_creds_opt **);
113 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE
114 # ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS
115 # define krb5_get_init_creds_opt_free(c, o) krb5_get_init_creds_opt_free(o)
118 # define krb5_get_init_creds_opt_free(c, o) free(o)
121 /* Heimdal-specific. */
122 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS
123 # define krb5_get_init_creds_opt_set_default_flags(c, p, r, o) /* empty */
127 * Heimdal: krb5_kt_free_entry, MIT: krb5_free_keytab_entry_contents. We
128 * check for the declaration rather than the function since the function is
129 * present in older MIT Kerberos libraries but not prototyped.
131 #if !HAVE_DECL_KRB5_KT_FREE_ENTRY
132 # define krb5_kt_free_entry(c, e) krb5_free_keytab_entry_contents((c), (e))
136 * Heimdal provides a nice function that just returns a const char *. On MIT,
137 * there's an accessor macro that returns the krb5_data pointer, which
138 * requires more work to get at the underlying char *.
140 #ifndef HAVE_KRB5_PRINCIPAL_GET_REALM
141 const char *krb5_principal_get_realm(krb5_context, krb5_const_principal);
144 /* Undo default visibility change. */
145 #pragma GCC visibility pop
149 #endif /* !PORTABLE_KRB5_H */