preauth_plugin.h 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527
  1. /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
  2. /*
  3. * Copyright (c) 2006 Red Hat, Inc.
  4. * Portions copyright (c) 2006, 2011 Massachusetts Institute of Technology
  5. * All Rights Reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions are met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in
  14. * the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Red Hat, Inc., nor the names of its
  17. * contributors may be used to endorse or promote products derived
  18. * from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
  21. * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  22. * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
  23. * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
  24. * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  25. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  26. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  27. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  28. * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  29. * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  30. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. */
  32. /*
  33. * Declarations for preauth plugin module implementors.
  34. *
  35. * This header defines two preauth interfaces, clpreauth and kdcpreauth. A
  36. * shared object can implement both interfaces or it can implement just one.
  37. *
  38. *
  39. * The clpreauth interface has a single supported major version, which is
  40. * 1. Major version 1 has a current minor version of 1. clpreauth modules
  41. * should define a function named clpreauth_<modulename>_initvt, matching
  42. * the signature:
  43. *
  44. * krb5_error_code
  45. * clpreauth_modname_initvt(krb5_context context, int maj_ver,
  46. * int min_ver, krb5_plugin_vtable vtable);
  47. *
  48. * The kdcpreauth interface has a single supported major version, which is 1.
  49. * Major version 1 has a current minor version of 1. kdcpreauth modules should
  50. * define a function named kdcpreauth_<modulename>_initvt, matching the
  51. * signature:
  52. *
  53. * krb5_error_code
  54. * kdcpreauth_modname_initvt(krb5_context context, int maj_ver, int min_ver,
  55. * krb5_plugin_vtable vtable);
  56. *
  57. * For both interfaces, the initvt function should:
  58. *
  59. * - Check that the supplied maj_ver number is supported by the module, or
  60. * return KRB5_PLUGIN_VER_NOTSUPP if it is not.
  61. *
  62. * - Cast the vtable pointer as appropriate for the interface and maj_ver:
  63. * clpreauth, maj_ver == 1: Cast to krb5_clpreauth_vtable
  64. * kdcpreauth, maj_ver == 1: Cast to krb5_kdcpreauth_vtable
  65. *
  66. * - Initialize the methods of the vtable, stopping as appropriate for the
  67. * supplied min_ver. Optional methods may be left uninitialized.
  68. *
  69. * Memory for the vtable is allocated by the caller, not by the module.
  70. */
  71. #ifndef KRB5_PREAUTH_PLUGIN_H_INCLUDED
  72. #define KRB5_PREAUTH_PLUGIN_H_INCLUDED
  73. #include <krb5/krb5.h>
  74. #include <krb5/plugin.h>
  75. /*
  76. * Preauth mechanism property flags, unified from previous definitions in the
  77. * KDC and libkrb5 sources.
  78. */
  79. /* Provides a real answer which we can send back to the KDC (client-only). The
  80. * client assumes that one real answer will be enough. */
  81. #define PA_REAL 0x00000001
  82. /* Doesn't provide a real answer, but must be given a chance to run before any
  83. * REAL mechanism callbacks (client-only). */
  84. #define PA_INFO 0x00000002
  85. /*
  86. * Causes the KDC to include this mechanism in a list of supported preauth
  87. * types if the user's DB entry flags the user as requiring hardware-based
  88. * preauthentication (KDC-only).
  89. */
  90. #define PA_HARDWARE 0x00000004
  91. /*
  92. * Causes the KDC to include this mechanism in a list of supported preauth
  93. * types if the user's DB entry flags the user as requiring preauthentication,
  94. * and to fail preauthentication if we can't verify the client data. The
  95. * flipside of PA_SUFFICIENT (KDC-only).
  96. */
  97. #define PA_REQUIRED 0x00000008
  98. /*
  99. * Causes the KDC to include this mechanism in a list of supported preauth
  100. * types if the user's DB entry flags the user as requiring preauthentication,
  101. * and to mark preauthentication as successful if we can verify the client
  102. * data. The flipside of PA_REQUIRED (KDC-only).
  103. */
  104. #define PA_SUFFICIENT 0x00000010
  105. /*
  106. * Marks this preauthentication mechanism as one which changes the key which is
  107. * used for encrypting the response to the client. Modules which have this
  108. * flag have their server_return_fn called before modules which do not, and are
  109. * passed over if a previously-called module has modified the encrypting key
  110. * (KDC-only).
  111. */
  112. #define PA_REPLACES_KEY 0x00000020
  113. /*
  114. * Not really a padata type, so don't include it in any list of preauth types
  115. * which gets sent over the wire.
  116. */
  117. #define PA_PSEUDO 0x00000080
  118. /*
  119. * For kdcpreauth mechanisms, indicates that e_data in non-FAST errors should
  120. * be encoded as typed data instead of padata.
  121. */
  122. #define PA_TYPED_E_DATA 0x00000100
  123. /*
  124. * clpreauth plugin interface definition.
  125. */
  126. /* Abstract type for a client request information handle. */
  127. typedef struct krb5_clpreauth_rock_st *krb5_clpreauth_rock;
  128. /* Abstract types for module data and per-request module data. */
  129. typedef struct krb5_clpreauth_moddata_st *krb5_clpreauth_moddata;
  130. typedef struct krb5_clpreauth_modreq_st *krb5_clpreauth_modreq;
  131. /* Before using a callback after version 1, modules must check the vers
  132. * field of the callback structure. */
  133. typedef struct krb5_clpreauth_callbacks_st {
  134. int vers;
  135. /*
  136. * Get the enctype expected to be used to encrypt the encrypted portion of
  137. * the AS_REP packet. When handling a PREAUTH_REQUIRED error, this
  138. * typically comes from etype-info2. When handling an AS reply, it is
  139. * initialized from the AS reply itself.
  140. */
  141. krb5_enctype (*get_etype)(krb5_context context, krb5_clpreauth_rock rock);
  142. /* Get a pointer to the FAST armor key, or NULL if the client is not using
  143. * FAST. The returned pointer is an alias and should not be freed. */
  144. krb5_keyblock *(*fast_armor)(krb5_context context,
  145. krb5_clpreauth_rock rock);
  146. /*
  147. * Get a pointer to the client-supplied reply key, possibly invoking the
  148. * prompter to ask for a password if this has not already been done. The
  149. * returned pointer is an alias and should not be freed.
  150. */
  151. krb5_error_code (*get_as_key)(krb5_context context,
  152. krb5_clpreauth_rock rock,
  153. krb5_keyblock **keyblock);
  154. /* Replace the reply key to be used to decrypt the AS response. */
  155. krb5_error_code (*set_as_key)(krb5_context context,
  156. krb5_clpreauth_rock rock,
  157. const krb5_keyblock *keyblock);
  158. /* End of version 1 clpreauth callbacks. */
  159. } *krb5_clpreauth_callbacks;
  160. /*
  161. * Optional: per-plugin initialization/cleanup. The init function is called by
  162. * libkrb5 when the plugin is loaded, and the fini function is called before
  163. * the plugin is unloaded. These may be called multiple times in case the
  164. * plugin is used in multiple contexts. The returned context lives the
  165. * lifetime of the krb5_context.
  166. */
  167. typedef krb5_error_code
  168. (*krb5_clpreauth_init_fn)(krb5_context context,
  169. krb5_clpreauth_moddata *moddata_out);
  170. typedef void
  171. (*krb5_clpreauth_fini_fn)(krb5_context context,
  172. krb5_clpreauth_moddata moddata);
  173. /*
  174. * Mandatory: Return flags indicating if the module is a "real" or an "info"
  175. * mechanism, and so on. This function is called for each entry in the
  176. * client_pa_type_list.
  177. */
  178. typedef int
  179. (*krb5_clpreauth_get_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
  180. /*
  181. * Optional: per-request initialization/cleanup. The request_init function is
  182. * called when beginning to process a get_init_creds request and the
  183. * request_fini function is called when processing of the request is complete.
  184. * This is optional. It may be called multiple times in the lifetime of a
  185. * krb5_context.
  186. */
  187. typedef void
  188. (*krb5_clpreauth_request_init_fn)(krb5_context context,
  189. krb5_clpreauth_moddata moddata,
  190. krb5_clpreauth_modreq *modreq_out);
  191. typedef void
  192. (*krb5_clpreauth_request_fini_fn)(krb5_context context,
  193. krb5_clpreauth_moddata moddata,
  194. krb5_clpreauth_modreq modreq);
  195. /*
  196. * Mandatory: process server-supplied data in pa_data and return created data
  197. * in pa_data_out. Also called after the AS-REP is received if the AS-REP
  198. * includes preauthentication data of the associated type.
  199. *
  200. * as_key contains the client-supplied key if known, or an empty keyblock if
  201. * not. If it is empty, the module may use gak_fct to fill it in.
  202. *
  203. * encoded_previous_request may be NULL if there has been no previous request
  204. * in the AS exchange.
  205. */
  206. typedef krb5_error_code
  207. (*krb5_clpreauth_process_fn)(krb5_context context,
  208. krb5_clpreauth_moddata moddata,
  209. krb5_clpreauth_modreq modreq,
  210. krb5_get_init_creds_opt *opt,
  211. krb5_clpreauth_callbacks cb,
  212. krb5_clpreauth_rock rock,
  213. krb5_kdc_req *request,
  214. krb5_data *encoded_request_body,
  215. krb5_data *encoded_previous_request,
  216. krb5_pa_data *pa_data,
  217. krb5_prompter_fct prompter, void *prompter_data,
  218. krb5_pa_data ***pa_data_out);
  219. /*
  220. * Optional: Attempt to use error and error_padata to try to recover from the
  221. * given error. To work with both FAST and non-FAST errors, an implementation
  222. * should generally consult error_padata rather than decoding error->e_data.
  223. * For non-FAST errors, it contains the e_data decoded as either pa-data or
  224. * typed-data.
  225. *
  226. * If this function is provided, and it returns 0 and stores data in
  227. * pa_data_out, then the client library will retransmit the request.
  228. */
  229. typedef krb5_error_code
  230. (*krb5_clpreauth_tryagain_fn)(krb5_context context,
  231. krb5_clpreauth_moddata moddata,
  232. krb5_clpreauth_modreq modreq,
  233. krb5_get_init_creds_opt *opt,
  234. krb5_clpreauth_callbacks cb,
  235. krb5_clpreauth_rock rock,
  236. krb5_kdc_req *request,
  237. krb5_data *encoded_request_body,
  238. krb5_data *encoded_previous_request,
  239. krb5_preauthtype pa_type,
  240. krb5_error *error,
  241. krb5_pa_data **error_padata,
  242. krb5_prompter_fct prompter, void *prompter_data,
  243. krb5_pa_data ***pa_data_out);
  244. /*
  245. * Optional: receive krb5_get_init_creds_opt information. The attr and value
  246. * information supplied should be copied into moddata by the module if it
  247. * wishes to reference it after returning from this call.
  248. */
  249. typedef krb5_error_code
  250. (*krb5_clpreauth_supply_gic_opts_fn)(krb5_context context,
  251. krb5_clpreauth_moddata moddata,
  252. krb5_get_init_creds_opt *opt,
  253. const char *attr, const char *value);
  254. typedef struct krb5_clpreauth_vtable_st {
  255. /* Mandatory: name of module. */
  256. char *name;
  257. /* Mandatory: pointer to zero-terminated list of pa_types which this module
  258. * can provide services for. */
  259. krb5_preauthtype *pa_type_list;
  260. /* Optional: pointer to zero-terminated list of enc_types which this module
  261. * claims to add support for. */
  262. krb5_enctype *enctype_list;
  263. krb5_clpreauth_init_fn init;
  264. krb5_clpreauth_fini_fn fini;
  265. krb5_clpreauth_get_flags_fn flags;
  266. krb5_clpreauth_request_init_fn request_init;
  267. krb5_clpreauth_request_fini_fn request_fini;
  268. krb5_clpreauth_process_fn process;
  269. krb5_clpreauth_tryagain_fn tryagain;
  270. krb5_clpreauth_supply_gic_opts_fn gic_opts;
  271. /* Minor version 1 ends here. */
  272. } *krb5_clpreauth_vtable;
  273. /*
  274. * This function allows a clpreauth plugin to obtain preauth options. The
  275. * preauth_data returned from this function should be freed by calling
  276. * krb5_get_init_creds_opt_free_pa().
  277. */
  278. krb5_error_code KRB5_CALLCONV
  279. krb5_get_init_creds_opt_get_pa(krb5_context context,
  280. krb5_get_init_creds_opt *opt,
  281. int *num_preauth_data,
  282. krb5_gic_opt_pa_data **preauth_data);
  283. /*
  284. * This function frees the preauth_data that was returned by
  285. * krb5_get_init_creds_opt_get_pa().
  286. */
  287. void KRB5_CALLCONV
  288. krb5_get_init_creds_opt_free_pa(krb5_context context,
  289. int num_preauth_data,
  290. krb5_gic_opt_pa_data *preauth_data);
  291. /*
  292. * kdcpreauth plugin interface definition.
  293. */
  294. /* Abstract type for a KDC callback data handle. */
  295. typedef struct krb5_kdcpreauth_rock_st *krb5_kdcpreauth_rock;
  296. /* Abstract type for module data and per-request module data. */
  297. typedef struct krb5_kdcpreauth_moddata_st *krb5_kdcpreauth_moddata;
  298. typedef struct krb5_kdcpreauth_modreq_st *krb5_kdcpreauth_modreq;
  299. /* The verto context structure type (typedef is in verto.h; we want to avoid a
  300. * header dependency for the moment). */
  301. struct verto_context;
  302. /* Before using a callback after version 1, modules must check the vers
  303. * field of the callback structure. */
  304. typedef struct krb5_kdcpreauth_callbacks_st {
  305. int vers;
  306. krb5_deltat (*max_time_skew)(krb5_context context,
  307. krb5_kdcpreauth_rock rock);
  308. /*
  309. * Get an array of krb5_keyblock structures containing the client keys
  310. * matching the request enctypes, terminated by an entry with key type = 0.
  311. * Returns ENOENT if no keys are available for the request enctypes. Free
  312. * the resulting object with the free_keys callback.
  313. */
  314. krb5_error_code (*client_keys)(krb5_context context,
  315. krb5_kdcpreauth_rock rock,
  316. krb5_keyblock **keys_out);
  317. /* Free the result of client_keys. */
  318. void (*free_keys)(krb5_context context, krb5_kdcpreauth_rock rock,
  319. krb5_keyblock *keys);
  320. /*
  321. * Get the encoded request body, which is sometimes needed for checksums.
  322. * For a FAST request this is the encoded inner request body. The returned
  323. * pointer is an alias and should not be freed.
  324. */
  325. krb5_data *(*request_body)(krb5_context context,
  326. krb5_kdcpreauth_rock rock);
  327. /* Get a pointer to the FAST armor key, or NULL if the request did not use
  328. * FAST. The returned pointer is an alias and should not be freed. */
  329. krb5_keyblock *(*fast_armor)(krb5_context context,
  330. krb5_kdcpreauth_rock rock);
  331. /* Retrieve a string attribute from the client DB entry, or NULL if no such
  332. * attribute is set. Free the result with the free_string callback. */
  333. krb5_error_code (*get_string)(krb5_context context,
  334. krb5_kdcpreauth_rock rock, const char *key,
  335. char **value_out);
  336. /* Free the result of get_string. */
  337. void (*free_string)(krb5_context context, krb5_kdcpreauth_rock rock,
  338. char *string);
  339. /* Get a pointer to the client DB entry (returned as a void pointer to
  340. * avoid a dependency on a libkdb5 type). */
  341. void *(*client_entry)(krb5_context context, krb5_kdcpreauth_rock rock);
  342. /* Get a pointer to the verto context which should be used by an
  343. * asynchronous edata or verify method. */
  344. struct verto_ctx *(*event_context)(krb5_context context,
  345. krb5_kdcpreauth_rock rock);
  346. /* End of version 1 kdcpreauth callbacks. */
  347. } *krb5_kdcpreauth_callbacks;
  348. /* Optional: preauth plugin initialization function. */
  349. typedef krb5_error_code
  350. (*krb5_kdcpreauth_init_fn)(krb5_context context,
  351. krb5_kdcpreauth_moddata *moddata_out,
  352. const char **realmnames);
  353. /* Optional: preauth plugin cleanup function. */
  354. typedef void
  355. (*krb5_kdcpreauth_fini_fn)(krb5_context context,
  356. krb5_kdcpreauth_moddata moddata);
  357. /*
  358. * Optional: return the flags which the KDC should use for this module. This
  359. * is a callback instead of a static value because the module may or may not
  360. * wish to count itself as a hardware preauthentication module (in other words,
  361. * the flags may be affected by the configuration, for example if a site
  362. * administrator can force a particular preauthentication type to be supported
  363. * using only hardware). This function is called for each entry entry in the
  364. * server_pa_type_list.
  365. */
  366. typedef int
  367. (*krb5_kdcpreauth_flags_fn)(krb5_context context, krb5_preauthtype pa_type);
  368. /*
  369. * Responder for krb5_kdcpreauth_edata_fn. If invoked with a non-zero code, pa
  370. * will be ignored and the padata type will not be included in the hint list.
  371. * If invoked with a zero code and a null pa value, the padata type will be
  372. * included in the list with an empty value. If invoked with a zero code and a
  373. * non-null pa value, pa will be included in the hint list and will later be
  374. * freed by the KDC.
  375. */
  376. typedef void
  377. (*krb5_kdcpreauth_edata_respond_fn)(void *arg, krb5_error_code code,
  378. krb5_pa_data *pa);
  379. /*
  380. * Optional: provide pa_data to send to the client as part of the "you need to
  381. * use preauthentication" error. The implementation must invoke the respond
  382. * when complete, whether successful or not, either before returning or
  383. * asynchronously using the verto context returned by cb->event_context().
  384. *
  385. * This function is not allowed to create a modreq object because we have no
  386. * guarantee that the client will ever make a follow-up request, or that it
  387. * will hit this KDC if it does.
  388. */
  389. typedef void
  390. (*krb5_kdcpreauth_edata_fn)(krb5_context context, krb5_kdc_req *request,
  391. krb5_kdcpreauth_callbacks cb,
  392. krb5_kdcpreauth_rock rock,
  393. krb5_kdcpreauth_moddata moddata,
  394. krb5_preauthtype pa_type,
  395. krb5_kdcpreauth_edata_respond_fn respond,
  396. void *arg);
  397. /*
  398. * Responder for krb5_kdcpreauth_verify_fn. Invoke with the arg parameter
  399. * supplied to verify, the error code (0 for success), an optional module
  400. * request state object to be consumed by return_fn or free_modreq_fn, optional
  401. * e_data to be passed to the caller if code is nonzero, and optional
  402. * authorization data to be included in the ticket. In non-FAST replies,
  403. * e_data will be encoded as typed-data if the module sets the PA_TYPED_E_DATA
  404. * flag, and as pa-data otherwise. e_data and authz_data will be freed by the
  405. * KDC.
  406. */
  407. typedef void
  408. (*krb5_kdcpreauth_verify_respond_fn)(void *arg, krb5_error_code code,
  409. krb5_kdcpreauth_modreq modreq,
  410. krb5_pa_data **e_data,
  411. krb5_authdata **authz_data);
  412. /*
  413. * Optional: verify preauthentication data sent by the client, setting the
  414. * TKT_FLG_PRE_AUTH or TKT_FLG_HW_AUTH flag in the enc_tkt_reply's "flags"
  415. * field as appropriate. The implementation must invoke the respond function
  416. * when complete, whether successful or not, either before returning or
  417. * asynchronously using the verto context returned by cb->event_context().
  418. */
  419. typedef void
  420. (*krb5_kdcpreauth_verify_fn)(krb5_context context,
  421. krb5_data *req_pkt, krb5_kdc_req *request,
  422. krb5_enc_tkt_part *enc_tkt_reply,
  423. krb5_pa_data *data,
  424. krb5_kdcpreauth_callbacks cb,
  425. krb5_kdcpreauth_rock rock,
  426. krb5_kdcpreauth_moddata moddata,
  427. krb5_kdcpreauth_verify_respond_fn respond,
  428. void *arg);
  429. /*
  430. * Optional: generate preauthentication response data to send to the client as
  431. * part of the AS-REP. If it needs to override the key which is used to
  432. * encrypt the response, it can do so.
  433. */
  434. typedef krb5_error_code
  435. (*krb5_kdcpreauth_return_fn)(krb5_context context,
  436. krb5_pa_data *padata,
  437. krb5_data *req_pkt,
  438. krb5_kdc_req *request,
  439. krb5_kdc_rep *reply,
  440. krb5_keyblock *encrypting_key,
  441. krb5_pa_data **send_pa_out,
  442. krb5_kdcpreauth_callbacks cb,
  443. krb5_kdcpreauth_rock rock,
  444. krb5_kdcpreauth_moddata moddata,
  445. krb5_kdcpreauth_modreq modreq);
  446. /* Optional: free a per-request context. */
  447. typedef void
  448. (*krb5_kdcpreauth_free_modreq_fn)(krb5_context,
  449. krb5_kdcpreauth_moddata moddata,
  450. krb5_kdcpreauth_modreq modreq);
  451. typedef struct krb5_kdcpreauth_vtable_st {
  452. /* Mandatory: name of module. */
  453. char *name;
  454. /* Mandatory: pointer to zero-terminated list of pa_types which this module
  455. * can provide services for. */
  456. krb5_preauthtype *pa_type_list;
  457. krb5_kdcpreauth_init_fn init;
  458. krb5_kdcpreauth_fini_fn fini;
  459. krb5_kdcpreauth_flags_fn flags;
  460. krb5_kdcpreauth_edata_fn edata;
  461. krb5_kdcpreauth_verify_fn verify;
  462. krb5_kdcpreauth_return_fn return_padata;
  463. krb5_kdcpreauth_free_modreq_fn free_modreq;
  464. } *krb5_kdcpreauth_vtable;
  465. #endif /* KRB5_PREAUTH_PLUGIN_H_INCLUDED */