1 /* 2 * Portability wrapper around krb5.h. 3 * 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. 7 * 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. 14 * 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. 18 * 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/>. 21 * 22 * Written by Russ Allbery <eagle@eyrie.org> 23 * Copyright 2015, 2017, 2020 Russ Allbery <eagle@eyrie.org> 24 * Copyright 2010-2014 25 * The Board of Trustees of the Leland Stanford Junior University 26 * 27 * Copying and distribution of this file, with or without modification, are 28 * permitted in any medium without royalty provided the copyright notice and 29 * this notice are preserved. This file is offered as-is, without any 30 * warranty. 31 * 32 * SPDX-License-Identifier: FSFAP 33 */ 34 35 #ifndef PORTABLE_KRB5_H 36 #define PORTABLE_KRB5_H 1 37 38 /* 39 * Allow inclusion of config.h to be skipped, since sometimes we have to use a 40 * stripped-down version of config.h with a different name. 41 */ 42 #ifndef CONFIG_H_INCLUDED 43 # include <config.h> 44 #endif 45 #include <portable/macros.h> 46 47 #if defined(HAVE_KRB5_H) 48 # include <krb5.h> 49 #elif defined(HAVE_KERBEROSV5_KRB5_H) 50 # include <kerberosv5/krb5.h> 51 #else 52 # include <krb5/krb5.h> 53 #endif 54 #include <stdlib.h> 55 56 /* Heimdal: KRB5_WELLKNOWN_NAME, MIT: KRB5_WELLKNOWN_NAMESTR. */ 57 #ifndef KRB5_WELLKNOWN_NAME 58 # ifdef KRB5_WELLKNOWN_NAMESTR 59 # define KRB5_WELLKNOWN_NAME KRB5_WELLKNOWN_NAMESTR 60 # else 61 # define KRB5_WELLKNOWN_NAME "WELLKNOWN" 62 # endif 63 #endif 64 65 /* Heimdal: KRB5_ANON_NAME, MIT: KRB5_ANONYMOUS_PRINCSTR. */ 66 #ifndef KRB5_ANON_NAME 67 # ifdef KRB5_ANONYMOUS_PRINCSTR 68 # define KRB5_ANON_NAME KRB5_ANONYMOUS_PRINCSTR 69 # else 70 # define KRB5_ANON_NAME "ANONYMOUS" 71 # endif 72 #endif 73 74 /* Heimdal: KRB5_ANON_REALM, MIT: KRB5_ANONYMOUS_REALMSTR. */ 75 #ifndef KRB5_ANON_REALM 76 # ifdef KRB5_ANONYMOUS_REALMSTR 77 # define KRB5_ANON_REALM KRB5_ANONYMOUS_REALMSTR 78 # else 79 # define KRB5_ANON_REALM "WELLKNOWN:ANONYMOUS" 80 # endif 81 #endif 82 83 BEGIN_DECLS 84 85 /* Default to a hidden visibility for all portability functions. */ 86 #pragma GCC visibility push(hidden) 87 88 /* 89 * AIX included Kerberos includes the profile library but not the 90 * krb5_appdefault functions, so we provide replacements that we have to 91 * prototype. 92 */ 93 #ifndef HAVE_KRB5_APPDEFAULT_STRING 94 void krb5_appdefault_boolean(krb5_context, const char *, const krb5_data *, 95 const char *, int, int *); 96 void krb5_appdefault_string(krb5_context, const char *, const krb5_data *, 97 const char *, const char *, char **); 98 #endif 99 100 /* 101 * Now present in both Heimdal and MIT, but very new in MIT and not present in 102 * older Heimdal. 103 */ 104 #ifndef HAVE_KRB5_CC_GET_FULL_NAME 105 krb5_error_code krb5_cc_get_full_name(krb5_context, krb5_ccache, char **); 106 #endif 107 108 /* Heimdal: krb5_data_free, MIT: krb5_free_data_contents. */ 109 #ifdef HAVE_KRB5_DATA_FREE 110 # define krb5_free_data_contents(c, d) krb5_data_free(d) 111 #endif 112 113 /* 114 * MIT-specific. The Heimdal documentation says to use free(), but that 115 * doesn't actually make sense since the memory is allocated inside the 116 * Kerberos library. Use krb5_xfree instead. 117 */ 118 #ifndef HAVE_KRB5_FREE_DEFAULT_REALM 119 # define krb5_free_default_realm(c, r) krb5_xfree(r) 120 #endif 121 122 /* 123 * Heimdal: krb5_xfree, MIT: krb5_free_string, older MIT uses free(). Note 124 * that we can incorrectly allocate in the library and call free() if 125 * krb5_free_string is not available but something we use that API for is 126 * available, such as krb5_appdefaults_*, but there isn't anything we can 127 * really do about it. 128 */ 129 #ifndef HAVE_KRB5_FREE_STRING 130 # ifdef HAVE_KRB5_XFREE 131 # define krb5_free_string(c, s) krb5_xfree(s) 132 # else 133 # define krb5_free_string(c, s) free(s) 134 # endif 135 #endif 136 137 /* Heimdal: krb5_xfree, MIT: krb5_free_unparsed_name. */ 138 #ifdef HAVE_KRB5_XFREE 139 # define krb5_free_unparsed_name(c, p) krb5_xfree(p) 140 #endif 141 142 /* 143 * krb5_{get,free}_error_message are the preferred APIs for both current MIT 144 * and current Heimdal, but there are tons of older APIs we may have to fall 145 * back on for earlier versions. 146 * 147 * This function should be called immediately after the corresponding error 148 * without any intervening Kerberos calls. Otherwise, the correct error 149 * message and supporting information may not be returned. 150 */ 151 #ifndef HAVE_KRB5_GET_ERROR_MESSAGE 152 const char *krb5_get_error_message(krb5_context, krb5_error_code); 153 #endif 154 #ifndef HAVE_KRB5_FREE_ERROR_MESSAGE 155 void krb5_free_error_message(krb5_context, const char *); 156 #endif 157 158 /* 159 * Both current MIT and current Heimdal prefer _opt_alloc and _opt_free, but 160 * older versions of both require allocating your own struct and calling 161 * _opt_init. 162 */ 163 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_ALLOC 164 krb5_error_code krb5_get_init_creds_opt_alloc(krb5_context, 165 krb5_get_init_creds_opt **); 166 #endif 167 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE 168 # ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_FREE_2_ARGS 169 # define krb5_get_init_creds_opt_free(c, o) \ 170 krb5_get_init_creds_opt_free(o) 171 # endif 172 #else 173 # define krb5_get_init_creds_opt_free(c, o) free(o) 174 #endif 175 176 /* Not available in versions of Heimdal prior to 7.0.1. */ 177 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_CHANGE_PASSWORD_PROMPT 178 # define krb5_get_init_creds_opt_set_change_password_prompt(o, f) /* */ 179 #endif 180 181 /* Heimdal-specific. */ 182 #ifndef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_DEFAULT_FLAGS 183 # define krb5_get_init_creds_opt_set_default_flags(c, p, r, o) /* empty */ 184 #endif 185 186 /* 187 * Old versions of Heimdal (0.7 and earlier) take only nine arguments to the 188 * krb5_get_init_creds_opt_set_pkinit instead of the 11 arguments that current 189 * versions take. Adjust if needed. This function is Heimdal-specific. 190 */ 191 #ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT 192 # ifdef HAVE_KRB5_GET_INIT_CREDS_OPT_SET_PKINIT_9_ARGS 193 # define krb5_get_init_creds_opt_set_pkinit(c, o, p, u, a, l, r, f, m, \ 194 d, s) \ 195 krb5_get_init_creds_opt_set_pkinit((c), (o), (p), (u), (a), (f), \ 196 (m), (d), (s)); 197 # endif 198 #endif 199 200 /* 201 * MIT-specific. Heimdal automatically ignores environment variables if 202 * called in a setuid context. 203 */ 204 #ifndef HAVE_KRB5_INIT_SECURE_CONTEXT 205 # define krb5_init_secure_context(c) krb5_init_context(c) 206 #endif 207 208 /* 209 * Heimdal: krb5_kt_free_entry, MIT: krb5_free_keytab_entry_contents. We 210 * check for the declaration rather than the function since the function is 211 * present in older MIT Kerberos libraries but not prototyped. 212 */ 213 #if !HAVE_DECL_KRB5_KT_FREE_ENTRY 214 # define krb5_kt_free_entry(c, e) krb5_free_keytab_entry_contents((c), (e)) 215 #endif 216 217 /* 218 * Heimdal provides a nice function that just returns a const char *. On MIT, 219 * there's an accessor macro that returns the krb5_data pointer, which 220 * requires more work to get at the underlying char *. 221 */ 222 #ifndef HAVE_KRB5_PRINCIPAL_GET_REALM 223 const char *krb5_principal_get_realm(krb5_context, krb5_const_principal); 224 #endif 225 226 /* 227 * krb5_change_password is deprecated in favor of krb5_set_password in current 228 * Heimdal. Current MIT provides both. 229 */ 230 #ifndef HAVE_KRB5_SET_PASSWORD 231 # define krb5_set_password(c, cr, pw, p, rc, rcs, rs) \ 232 krb5_change_password((c), (cr), (pw), (rc), (rcs), (rs)) 233 #endif 234 235 /* 236 * AIX's NAS Kerberos implementation mysteriously provides the struct and the 237 * krb5_verify_init_creds function but not this function. 238 */ 239 #ifndef HAVE_KRB5_VERIFY_INIT_CREDS_OPT_INIT 240 void krb5_verify_init_creds_opt_init(krb5_verify_init_creds_opt *opt); 241 #endif 242 243 /* Undo default visibility change. */ 244 #pragma GCC visibility pop 245 246 END_DECLS 247 248 #endif /* !PORTABLE_KRB5_H */ 249