Home | History | Annotate | Line # | Download | only in krb5
      1 /*	$NetBSD: deprecated.c,v 1.4 2023/06/19 21:41:44 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 1997 - 2009 Kungliga Tekniska Hgskolan
      5  * (Royal Institute of Technology, Stockholm, Sweden).
      6  * All rights reserved.
      7  *
      8  * Redistribution and use in source and binary forms, with or without
      9  * modification, are permitted provided that the following conditions
     10  * are met:
     11  *
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  *
     15  * 2. Redistributions in binary form must reproduce the above copyright
     16  *    notice, this list of conditions and the following disclaimer in the
     17  *    documentation and/or other materials provided with the distribution.
     18  *
     19  * 3. Neither the name of the Institute nor the names of its contributors
     20  *    may be used to endorse or promote products derived from this software
     21  *    without specific prior written permission.
     22  *
     23  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
     24  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
     27  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     28  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     29  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     32  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     33  * SUCH DAMAGE.
     34  */
     35 
     36 #ifdef __GNUC__
     37 /* For some GCCs there's no way to shut them up about deprecated functions */
     38 #define KRB5_DEPRECATED_FUNCTION(x)
     39 #endif
     40 
     41 #include "krb5_locl.h"
     42 
     43 
     44 #undef __attribute__
     45 #define __attribute__(x)
     46 
     47 #ifndef HEIMDAL_SMALLER
     48 
     49 /**
     50  * Same as krb5_data_free(). MIT compat.
     51  *
     52  * Deprecated: use krb5_data_free().
     53  *
     54  * @param context Kerberos 5 context.
     55  * @param data krb5_data to free.
     56  *
     57  * @ingroup krb5_deprecated
     58  */
     59 
     60 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
     61 krb5_free_data_contents(krb5_context context, krb5_data *data)
     62     KRB5_DEPRECATED_FUNCTION("Use X instead")
     63 {
     64     krb5_data_free(data);
     65 }
     66 
     67 /**
     68  * Deprecated: keytypes doesn't exists, they are really enctypes.
     69  *
     70  * @ingroup krb5_deprecated
     71  */
     72 
     73 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
     74 krb5_keytype_to_enctypes_default (krb5_context context,
     75 				  krb5_keytype keytype,
     76 				  unsigned *len,
     77 				  krb5_enctype **val)
     78     KRB5_DEPRECATED_FUNCTION("Use X instead")
     79 {
     80     unsigned int i, n;
     81     krb5_enctype *ret;
     82 
     83     if (keytype != (krb5_keytype)KEYTYPE_DES || context->etypes_des == NULL)
     84 	return krb5_keytype_to_enctypes (context, keytype, len, val);
     85 
     86     for (n = 0; context->etypes_des[n]; ++n)
     87 	;
     88     ret = malloc (n * sizeof(*ret));
     89     if (ret == NULL && n != 0)
     90 	return krb5_enomem(context);
     91     for (i = 0; i < n; ++i)
     92 	ret[i] = context->etypes_des[i];
     93     *len = n;
     94     *val = ret;
     95     return 0;
     96 }
     97 
     98 
     99 static struct {
    100     const char *name;
    101     krb5_keytype type;
    102 } keys[] = {
    103     { "null", KRB5_ENCTYPE_NULL },
    104     { "des", KRB5_ENCTYPE_DES_CBC_CRC },
    105     { "des3", KRB5_ENCTYPE_OLD_DES3_CBC_SHA1 },
    106     { "aes-128", KRB5_ENCTYPE_AES128_CTS_HMAC_SHA1_96 },
    107     { "aes-256", KRB5_ENCTYPE_AES256_CTS_HMAC_SHA1_96 },
    108     { "arcfour", KRB5_ENCTYPE_ARCFOUR_HMAC_MD5 },
    109     { "arcfour-56", KRB5_ENCTYPE_ARCFOUR_HMAC_MD5_56 }
    110 };
    111 
    112 static int num_keys = sizeof(keys) / sizeof(keys[0]);
    113 
    114 /**
    115  * Deprecated: keytypes doesn't exists, they are really enctypes in
    116  * most cases, use krb5_enctype_to_string().
    117  *
    118  * @ingroup krb5_deprecated
    119  */
    120 
    121 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    122 krb5_keytype_to_string(krb5_context context,
    123 		       krb5_keytype keytype,
    124 		       char **string)
    125     KRB5_DEPRECATED_FUNCTION("Use X instead")
    126 {
    127     const char *name = NULL;
    128     int i;
    129 
    130     for(i = 0; i < num_keys; i++) {
    131 	if(keys[i].type == keytype) {
    132 	    name = keys[i].name;
    133 	    break;
    134 	}
    135     }
    136 
    137     if(i >= num_keys) {
    138 	krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
    139 			       "key type %d not supported", keytype);
    140 	return KRB5_PROG_KEYTYPE_NOSUPP;
    141     }
    142     *string = strdup(name);
    143     if (*string == NULL)
    144 	return krb5_enomem(context);
    145     return 0;
    146 }
    147 
    148 /**
    149  * Deprecated: keytypes doesn't exists, they are really enctypes in
    150  * most cases, use krb5_string_to_enctype().
    151  *
    152  * @ingroup krb5_deprecated
    153  */
    154 
    155 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    156 krb5_string_to_keytype(krb5_context context,
    157 		       const char *string,
    158 		       krb5_keytype *keytype)
    159     KRB5_DEPRECATED_FUNCTION("Use X instead")
    160 {
    161     char *end;
    162     int i;
    163 
    164     for(i = 0; i < num_keys; i++)
    165 	if(strcasecmp(keys[i].name, string) == 0){
    166 	    *keytype = keys[i].type;
    167 	    return 0;
    168 	}
    169 
    170     /* check if the enctype is a number */
    171     *keytype = strtol(string, &end, 0);
    172     if(*end == '\0' && *keytype != 0) {
    173 	if (krb5_enctype_valid(context, *keytype) == 0)
    174 	    return 0;
    175     }
    176 
    177     krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP,
    178 			   "key type %s not supported", string);
    179     return KRB5_PROG_KEYTYPE_NOSUPP;
    180 }
    181 
    182 /**
    183  * Deprecated: use krb5_get_init_creds() and friends.
    184  *
    185  * @ingroup krb5_deprecated
    186  */
    187 
    188 KRB5_LIB_FUNCTION krb5_error_code KRB5_CALLCONV
    189 krb5_password_key_proc (krb5_context context,
    190 			krb5_enctype type,
    191 			krb5_salt salt,
    192 			krb5_const_pointer keyseed,
    193 			krb5_keyblock **key)
    194     KRB5_DEPRECATED_FUNCTION("Use X instead")
    195 {
    196     krb5_error_code ret;
    197     const char *password = (const char *)keyseed;
    198     char buf[BUFSIZ];
    199 
    200     *key = malloc (sizeof (**key));
    201     if (*key == NULL)
    202 	return krb5_enomem(context);
    203     if (password == NULL) {
    204 	if(UI_UTIL_read_pw_string (buf, sizeof(buf), "Password: ", 0)) {
    205 	    free (*key);
    206 	    krb5_clear_error_message(context);
    207 	    return KRB5_LIBOS_PWDINTR;
    208 	}
    209 	password = buf;
    210     }
    211     ret = krb5_string_to_key_salt (context, type, password, salt, *key);
    212     memset_s(buf, sizeof(buf), 0, sizeof(buf));
    213     return ret;
    214 }
    215 
    216 /**
    217  * Deprecated: use krb5_get_init_creds() and friends.
    218  *
    219  * @ingroup krb5_deprecated
    220  */
    221 
    222 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    223 krb5_get_in_tkt_with_password (krb5_context context,
    224 			       krb5_flags options,
    225 			       krb5_addresses *addrs,
    226 			       const krb5_enctype *etypes,
    227 			       const krb5_preauthtype *pre_auth_types,
    228 			       const char *password,
    229 			       krb5_ccache ccache,
    230 			       krb5_creds *creds,
    231 			       krb5_kdc_rep *ret_as_reply)
    232     KRB5_DEPRECATED_FUNCTION("Use X instead")
    233 {
    234      return krb5_get_in_tkt (context,
    235 			     options,
    236 			     addrs,
    237 			     etypes,
    238 			     pre_auth_types,
    239 			     krb5_password_key_proc,
    240 			     password,
    241 			     NULL,
    242 			     NULL,
    243 			     creds,
    244 			     ccache,
    245 			     ret_as_reply);
    246 }
    247 
    248 static krb5_error_code KRB5_CALLCONV
    249 krb5_skey_key_proc (krb5_context context,
    250 		    krb5_enctype type,
    251 		    krb5_salt salt,
    252 		    krb5_const_pointer keyseed,
    253 		    krb5_keyblock **key)
    254 {
    255     return krb5_copy_keyblock (context, keyseed, key);
    256 }
    257 
    258 /**
    259  * Deprecated: use krb5_get_init_creds() and friends.
    260  *
    261  * @ingroup krb5_deprecated
    262  */
    263 
    264 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    265 krb5_get_in_tkt_with_skey (krb5_context context,
    266 			   krb5_flags options,
    267 			   krb5_addresses *addrs,
    268 			   const krb5_enctype *etypes,
    269 			   const krb5_preauthtype *pre_auth_types,
    270 			   const krb5_keyblock *key,
    271 			   krb5_ccache ccache,
    272 			   krb5_creds *creds,
    273 			   krb5_kdc_rep *ret_as_reply)
    274     KRB5_DEPRECATED_FUNCTION("Use X instead")
    275 {
    276     if(key == NULL)
    277 	return krb5_get_in_tkt_with_keytab (context,
    278 					    options,
    279 					    addrs,
    280 					    etypes,
    281 					    pre_auth_types,
    282 					    NULL,
    283 					    ccache,
    284 					    creds,
    285 					    ret_as_reply);
    286     else
    287 	return krb5_get_in_tkt (context,
    288 				options,
    289 				addrs,
    290 				etypes,
    291 				pre_auth_types,
    292 				krb5_skey_key_proc,
    293 				key,
    294 				NULL,
    295 				NULL,
    296 				creds,
    297 				ccache,
    298 				ret_as_reply);
    299 }
    300 
    301 /**
    302  * Deprecated: use krb5_get_init_creds() and friends.
    303  *
    304  * @ingroup krb5_deprecated
    305  */
    306 
    307 KRB5_LIB_FUNCTION krb5_error_code KRB5_CALLCONV
    308 krb5_keytab_key_proc (krb5_context context,
    309 		      krb5_enctype enctype,
    310 		      krb5_salt salt,
    311 		      krb5_const_pointer keyseed,
    312 		      krb5_keyblock **key)
    313     KRB5_DEPRECATED_FUNCTION("Use X instead")
    314 {
    315     krb5_keytab_key_proc_args *args  = rk_UNCONST(keyseed);
    316     krb5_keytab keytab = args->keytab;
    317     krb5_principal principal  = args->principal;
    318     krb5_error_code ret;
    319     krb5_keytab real_keytab;
    320     krb5_keytab_entry entry;
    321 
    322     if(keytab == NULL)
    323 	krb5_kt_default(context, &real_keytab);
    324     else
    325 	real_keytab = keytab;
    326 
    327     ret = krb5_kt_get_entry (context, real_keytab, principal,
    328 			     0, enctype, &entry);
    329     if (ret == 0) {
    330         ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    331         krb5_kt_free_entry(context, &entry);
    332     }
    333 
    334     if (keytab == NULL)
    335 	krb5_kt_close (context, real_keytab);
    336     return ret;
    337 }
    338 
    339 /**
    340  * Deprecated: use krb5_get_init_creds() and friends.
    341  *
    342  * @ingroup krb5_deprecated
    343  */
    344 
    345 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    346 krb5_get_in_tkt_with_keytab (krb5_context context,
    347 			     krb5_flags options,
    348 			     krb5_addresses *addrs,
    349 			     const krb5_enctype *etypes,
    350 			     const krb5_preauthtype *pre_auth_types,
    351 			     krb5_keytab keytab,
    352 			     krb5_ccache ccache,
    353 			     krb5_creds *creds,
    354 			     krb5_kdc_rep *ret_as_reply)
    355     KRB5_DEPRECATED_FUNCTION("Use X instead")
    356 {
    357     krb5_keytab_key_proc_args a;
    358 
    359     a.principal = creds->client;
    360     a.keytab    = keytab;
    361 
    362     return krb5_get_in_tkt (context,
    363 			    options,
    364 			    addrs,
    365 			    etypes,
    366 			    pre_auth_types,
    367 			    krb5_keytab_key_proc,
    368 			    &a,
    369 			    NULL,
    370 			    NULL,
    371 			    creds,
    372 			    ccache,
    373 			    ret_as_reply);
    374 }
    375 
    376 /**
    377  * Generate a new ccache of type `ops' in `id'.
    378  *
    379  * Deprecated: use krb5_cc_new_unique() instead.
    380  *
    381  * @return Return an error code or 0, see krb5_get_error_message().
    382  *
    383  * @ingroup krb5_ccache
    384  */
    385 
    386 
    387 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    388 krb5_cc_gen_new(krb5_context context,
    389 		const krb5_cc_ops *ops,
    390 		krb5_ccache *id)
    391     KRB5_DEPRECATED_FUNCTION("Use X instead")
    392 {
    393     return krb5_cc_new_unique(context, ops->prefix, NULL, id);
    394 }
    395 
    396 /**
    397  * Deprecated: use krb5_principal_get_realm()
    398  *
    399  * @ingroup krb5_deprecated
    400  */
    401 
    402 KRB5_LIB_FUNCTION krb5_realm * KRB5_LIB_CALL
    403 krb5_princ_realm(krb5_context context,
    404 		 krb5_principal principal)
    405     KRB5_DEPRECATED_FUNCTION("Use X instead")
    406 {
    407     return &principal->realm;
    408 }
    409 
    410 
    411 /**
    412  * Deprecated: use krb5_principal_set_realm()
    413  *
    414  * @ingroup krb5_deprecated
    415  */
    416 
    417 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    418 krb5_princ_set_realm(krb5_context context,
    419 		     krb5_principal principal,
    420 		     krb5_realm *realm)
    421     KRB5_DEPRECATED_FUNCTION("Use X instead")
    422 {
    423     principal->realm = *realm;
    424 }
    425 
    426 /**
    427  * Deprecated: use krb5_free_cred_contents()
    428  *
    429  * @ingroup krb5_deprecated
    430  */
    431 
    432 /* keep this for compatibility with older code */
    433 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    434 krb5_free_creds_contents (krb5_context context, krb5_creds *c)
    435     KRB5_DEPRECATED_FUNCTION("Use X instead")
    436 {
    437     return krb5_free_cred_contents (context, c);
    438 }
    439 
    440 /**
    441  * Free the error message returned by krb5_get_error_string().
    442  *
    443  * Deprecated: use krb5_free_error_message()
    444  *
    445  * @param context Kerberos context
    446  * @param str error message to free
    447  *
    448  * @ingroup krb5_deprecated
    449  */
    450 
    451 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    452 krb5_free_error_string(krb5_context context, char *str)
    453     KRB5_DEPRECATED_FUNCTION("Use X instead")
    454 {
    455     krb5_free_error_message(context, str);
    456 }
    457 
    458 /**
    459  * Set the error message returned by krb5_get_error_string().
    460  *
    461  * Deprecated: use krb5_get_error_message()
    462  *
    463  * @param context Kerberos context
    464  * @param fmt error message to free
    465  *
    466  * @return Return an error code or 0.
    467  *
    468  * @ingroup krb5_deprecated
    469  */
    470 
    471 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    472 krb5_set_error_string(krb5_context context, const char *fmt, ...)
    473     __attribute__ ((__format__ (__printf__, 2, 3)))
    474     KRB5_DEPRECATED_FUNCTION("Use X instead")
    475 {
    476     va_list ap;
    477 
    478     va_start(ap, fmt);
    479     krb5_vset_error_message (context, 0, fmt, ap);
    480     va_end(ap);
    481     return 0;
    482 }
    483 
    484 /**
    485  * Set the error message returned by krb5_get_error_string(),
    486  * deprecated, use krb5_set_error_message().
    487  *
    488  * Deprecated: use krb5_vset_error_message()
    489  *
    490  * @param context Kerberos context
    491  * @param fmt error message to free
    492  * @param args variable argument list vector
    493  *
    494  * @return Return an error code or 0.
    495  *
    496  * @ingroup krb5_deprecated
    497  */
    498 
    499 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    500 krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
    501     __attribute__ ((__format__ (__printf__, 2, 0)))
    502     KRB5_DEPRECATED_FUNCTION("Use X instead")
    503 {
    504     krb5_vset_error_message(context, 0, fmt, args);
    505     return 0;
    506 }
    507 
    508 /**
    509  * Clear the error message returned by krb5_get_error_string().
    510  *
    511  * Deprecated: use krb5_clear_error_message()
    512  *
    513  * @param context Kerberos context
    514  *
    515  * @ingroup krb5_deprecated
    516  */
    517 
    518 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    519 krb5_clear_error_string(krb5_context context)
    520     KRB5_DEPRECATED_FUNCTION("Use X instead")
    521 {
    522     krb5_clear_error_message(context);
    523 }
    524 
    525 /**
    526  * Deprecated: use krb5_get_credentials_with_flags().
    527  *
    528  * @ingroup krb5_deprecated
    529  */
    530 
    531 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    532 krb5_get_cred_from_kdc_opt(krb5_context context,
    533 			   krb5_ccache ccache,
    534 			   krb5_creds *in_creds,
    535 			   krb5_creds **out_creds,
    536 			   krb5_creds ***ret_tgts,
    537 			   krb5_flags flags)
    538     KRB5_DEPRECATED_FUNCTION("Use X instead")
    539 {
    540     krb5_kdc_flags f;
    541     f.i = flags;
    542     return _krb5_get_cred_kdc_any(context, f, ccache,
    543 				  in_creds, NULL, NULL,
    544 				  out_creds, ret_tgts);
    545 }
    546 
    547 /**
    548  * Deprecated: use krb5_get_credentials_with_flags().
    549  *
    550  * @ingroup krb5_deprecated
    551  */
    552 
    553 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    554 krb5_get_cred_from_kdc(krb5_context context,
    555 		       krb5_ccache ccache,
    556 		       krb5_creds *in_creds,
    557 		       krb5_creds **out_creds,
    558 		       krb5_creds ***ret_tgts)
    559     KRB5_DEPRECATED_FUNCTION("Use X instead")
    560 {
    561     return krb5_get_cred_from_kdc_opt(context, ccache,
    562 				      in_creds, out_creds, ret_tgts, 0);
    563 }
    564 
    565 /**
    566  * Deprecated: use krb5_xfree().
    567  *
    568  * @ingroup krb5_deprecated
    569  */
    570 
    571 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    572 krb5_free_unparsed_name(krb5_context context, char *str)
    573     KRB5_DEPRECATED_FUNCTION("Use X instead")
    574 {
    575     krb5_xfree(str);
    576 }
    577 
    578 /**
    579  * Deprecated: use krb5_generate_subkey_extended()
    580  *
    581  * @ingroup krb5_deprecated
    582  */
    583 
    584 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    585 krb5_generate_subkey(krb5_context context,
    586 		     const krb5_keyblock *key,
    587 		     krb5_keyblock **subkey)
    588     KRB5_DEPRECATED_FUNCTION("Use X instead")
    589 {
    590     return krb5_generate_subkey_extended(context, key, ETYPE_NULL, subkey);
    591 }
    592 
    593 /**
    594  * Deprecated: use krb5_auth_con_getremoteseqnumber()
    595  *
    596  * @ingroup krb5_deprecated
    597  */
    598 
    599 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    600 krb5_auth_getremoteseqnumber(krb5_context context,
    601 			     krb5_auth_context auth_context,
    602 			     int32_t *seqnumber)
    603     KRB5_DEPRECATED_FUNCTION("Use X instead")
    604 {
    605   *seqnumber = auth_context->remote_seqnumber;
    606   return 0;
    607 }
    608 
    609 /**
    610  * Return the error message in context. On error or no error string,
    611  * the function returns NULL.
    612  *
    613  * @param context Kerberos 5 context
    614  *
    615  * @return an error string, needs to be freed with
    616  * krb5_free_error_message(). The functions return NULL on error.
    617  *
    618  * @ingroup krb5_error
    619  */
    620 
    621 KRB5_LIB_FUNCTION char * KRB5_LIB_CALL
    622 krb5_get_error_string(krb5_context context)
    623     KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead")
    624 {
    625     char *ret = NULL;
    626 
    627     HEIMDAL_MUTEX_lock(&context->mutex);
    628     if (context->error_string)
    629 	ret = strdup(context->error_string);
    630     HEIMDAL_MUTEX_unlock(&context->mutex);
    631     return ret;
    632 }
    633 
    634 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
    635 krb5_have_error_string(krb5_context context)
    636     KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead")
    637 {
    638     char *str;
    639     HEIMDAL_MUTEX_lock(&context->mutex);
    640     str = context->error_string;
    641     HEIMDAL_MUTEX_unlock(&context->mutex);
    642     return str != NULL;
    643 }
    644 
    645 struct send_to_kdc {
    646     krb5_send_to_kdc_func func;
    647     void *data;
    648 };
    649 
    650 /*
    651  * Send the data `send' to one host from `handle` and get back the reply
    652  * in `receive'.
    653  */
    654 
    655 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    656 krb5_sendto (krb5_context context,
    657 	     const krb5_data *send_data,
    658 	     krb5_krbhst_handle handle,
    659 	     krb5_data *receive)
    660 {
    661     krb5_error_code ret;
    662     krb5_sendto_ctx ctx;
    663 
    664     ret = krb5_sendto_ctx_alloc(context, &ctx);
    665     if (ret)
    666 	return ret;
    667     _krb5_sendto_ctx_set_krb5hst(context, ctx, handle);
    668 
    669     ret = krb5_sendto_context(context, ctx, send_data, (char *)_krb5_krbhst_get_realm(handle), receive);
    670     krb5_sendto_ctx_free(context, ctx);
    671     return ret;
    672 }
    673 
    674 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    675 krb5_sendto_kdc(krb5_context context,
    676 		const krb5_data *send_data,
    677 		const krb5_realm *realm,
    678 		krb5_data *receive)
    679 {
    680     return krb5_sendto_kdc_flags(context, send_data, realm, receive, 0);
    681 }
    682 
    683 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    684 krb5_sendto_kdc_flags(krb5_context context,
    685 		      const krb5_data *send_data,
    686 		      const krb5_realm *realm,
    687 		      krb5_data *receive,
    688 		      int flags)
    689 {
    690     krb5_error_code ret;
    691     krb5_sendto_ctx ctx;
    692 
    693     ret = krb5_sendto_ctx_alloc(context, &ctx);
    694     if (ret)
    695 	return ret;
    696     krb5_sendto_ctx_add_flags(ctx, flags);
    697     krb5_sendto_ctx_set_func(ctx, _krb5_kdc_retry, NULL);
    698 
    699     ret = krb5_sendto_context(context, ctx, send_data, *realm, receive);
    700     krb5_sendto_ctx_free(context, ctx);
    701     return ret;
    702 }
    703 
    704 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    705 krb5_set_send_to_kdc_func(krb5_context context,
    706 			  krb5_send_to_kdc_func func,
    707 			  void *data)
    708 {
    709     free(context->send_to_kdc);
    710     if (func == NULL) {
    711 	context->send_to_kdc = NULL;
    712 	return 0;
    713     }
    714 
    715     context->send_to_kdc = malloc(sizeof(*context->send_to_kdc));
    716     if (context->send_to_kdc == NULL) {
    717 	krb5_set_error_message(context, ENOMEM,
    718 			       N_("malloc: out of memory", ""));
    719 	return ENOMEM;
    720     }
    721 
    722     context->send_to_kdc->func = func;
    723     context->send_to_kdc->data = data;
    724     return 0;
    725 }
    726 
    727 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    728 _krb5_copy_send_to_kdc_func(krb5_context context, krb5_context to)
    729 {
    730     if (context->send_to_kdc)
    731 	return krb5_set_send_to_kdc_func(to,
    732 					 context->send_to_kdc->func,
    733 					 context->send_to_kdc->data);
    734     else
    735 	return krb5_set_send_to_kdc_func(to, NULL, NULL);
    736 }
    737 
    738 #endif /* HEIMDAL_SMALLER */
    739