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