Home | History | Annotate | Line # | Download | only in krb5
deprecated.c revision 1.1.1.3
      1 /*	$NetBSD: deprecated.c,v 1.1.1.3 2017/01/28 20:46:51 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 (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 
    330     if (keytab == NULL)
    331 	krb5_kt_close (context, real_keytab);
    332 
    333     if (ret)
    334 	return ret;
    335 
    336     ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    337     krb5_kt_free_entry(context, &entry);
    338     return ret;
    339 }
    340 
    341 /**
    342  * Deprecated: use krb5_get_init_creds() and friends.
    343  *
    344  * @ingroup krb5_deprecated
    345  */
    346 
    347 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    348 krb5_get_in_tkt_with_keytab (krb5_context context,
    349 			     krb5_flags options,
    350 			     krb5_addresses *addrs,
    351 			     const krb5_enctype *etypes,
    352 			     const krb5_preauthtype *pre_auth_types,
    353 			     krb5_keytab keytab,
    354 			     krb5_ccache ccache,
    355 			     krb5_creds *creds,
    356 			     krb5_kdc_rep *ret_as_reply)
    357     KRB5_DEPRECATED_FUNCTION("Use X instead")
    358 {
    359     krb5_keytab_key_proc_args a;
    360 
    361     a.principal = creds->client;
    362     a.keytab    = keytab;
    363 
    364     return krb5_get_in_tkt (context,
    365 			    options,
    366 			    addrs,
    367 			    etypes,
    368 			    pre_auth_types,
    369 			    krb5_keytab_key_proc,
    370 			    &a,
    371 			    NULL,
    372 			    NULL,
    373 			    creds,
    374 			    ccache,
    375 			    ret_as_reply);
    376 }
    377 
    378 /**
    379  * Generate a new ccache of type `ops' in `id'.
    380  *
    381  * Deprecated: use krb5_cc_new_unique() instead.
    382  *
    383  * @return Return an error code or 0, see krb5_get_error_message().
    384  *
    385  * @ingroup krb5_ccache
    386  */
    387 
    388 
    389 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    390 krb5_cc_gen_new(krb5_context context,
    391 		const krb5_cc_ops *ops,
    392 		krb5_ccache *id)
    393     KRB5_DEPRECATED_FUNCTION("Use X instead")
    394 {
    395     return krb5_cc_new_unique(context, ops->prefix, NULL, id);
    396 }
    397 
    398 /**
    399  * Deprecated: use krb5_principal_get_realm()
    400  *
    401  * @ingroup krb5_deprecated
    402  */
    403 
    404 KRB5_LIB_FUNCTION krb5_realm * KRB5_LIB_CALL
    405 krb5_princ_realm(krb5_context context,
    406 		 krb5_principal principal)
    407     KRB5_DEPRECATED_FUNCTION("Use X instead")
    408 {
    409     return &principal->realm;
    410 }
    411 
    412 
    413 /**
    414  * Deprecated: use krb5_principal_set_realm()
    415  *
    416  * @ingroup krb5_deprecated
    417  */
    418 
    419 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    420 krb5_princ_set_realm(krb5_context context,
    421 		     krb5_principal principal,
    422 		     krb5_realm *realm)
    423     KRB5_DEPRECATED_FUNCTION("Use X instead")
    424 {
    425     principal->realm = *realm;
    426 }
    427 
    428 /**
    429  * Deprecated: use krb5_free_cred_contents()
    430  *
    431  * @ingroup krb5_deprecated
    432  */
    433 
    434 /* keep this for compatibility with older code */
    435 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    436 krb5_free_creds_contents (krb5_context context, krb5_creds *c)
    437     KRB5_DEPRECATED_FUNCTION("Use X instead")
    438 {
    439     return krb5_free_cred_contents (context, c);
    440 }
    441 
    442 /**
    443  * Free the error message returned by krb5_get_error_string().
    444  *
    445  * Deprecated: use krb5_free_error_message()
    446  *
    447  * @param context Kerberos context
    448  * @param str error message to free
    449  *
    450  * @ingroup krb5_deprecated
    451  */
    452 
    453 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    454 krb5_free_error_string(krb5_context context, char *str)
    455     KRB5_DEPRECATED_FUNCTION("Use X instead")
    456 {
    457     krb5_free_error_message(context, str);
    458 }
    459 
    460 /**
    461  * Set the error message returned by krb5_get_error_string().
    462  *
    463  * Deprecated: use krb5_get_error_message()
    464  *
    465  * @param context Kerberos context
    466  * @param fmt error message to free
    467  *
    468  * @return Return an error code or 0.
    469  *
    470  * @ingroup krb5_deprecated
    471  */
    472 
    473 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    474 krb5_set_error_string(krb5_context context, const char *fmt, ...)
    475     __attribute__((format (printf, 2, 3)))
    476     KRB5_DEPRECATED_FUNCTION("Use X instead")
    477 {
    478     va_list ap;
    479 
    480     va_start(ap, fmt);
    481     krb5_vset_error_message (context, 0, fmt, ap);
    482     va_end(ap);
    483     return 0;
    484 }
    485 
    486 /**
    487  * Set the error message returned by krb5_get_error_string(),
    488  * deprecated, use krb5_set_error_message().
    489  *
    490  * Deprecated: use krb5_vset_error_message()
    491  *
    492  * @param context Kerberos context
    493  * @param fmt error message to free
    494  * @param args variable argument list vector
    495  *
    496  * @return Return an error code or 0.
    497  *
    498  * @ingroup krb5_deprecated
    499  */
    500 
    501 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    502 krb5_vset_error_string(krb5_context context, const char *fmt, va_list args)
    503     __attribute__ ((format (printf, 2, 0)))
    504     KRB5_DEPRECATED_FUNCTION("Use X instead")
    505 {
    506     krb5_vset_error_message(context, 0, fmt, args);
    507     return 0;
    508 }
    509 
    510 /**
    511  * Clear the error message returned by krb5_get_error_string().
    512  *
    513  * Deprecated: use krb5_clear_error_message()
    514  *
    515  * @param context Kerberos context
    516  *
    517  * @ingroup krb5_deprecated
    518  */
    519 
    520 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    521 krb5_clear_error_string(krb5_context context)
    522     KRB5_DEPRECATED_FUNCTION("Use X instead")
    523 {
    524     krb5_clear_error_message(context);
    525 }
    526 
    527 /**
    528  * Deprecated: use krb5_get_credentials_with_flags().
    529  *
    530  * @ingroup krb5_deprecated
    531  */
    532 
    533 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    534 krb5_get_cred_from_kdc_opt(krb5_context context,
    535 			   krb5_ccache ccache,
    536 			   krb5_creds *in_creds,
    537 			   krb5_creds **out_creds,
    538 			   krb5_creds ***ret_tgts,
    539 			   krb5_flags flags)
    540     KRB5_DEPRECATED_FUNCTION("Use X instead")
    541 {
    542     krb5_kdc_flags f;
    543     f.i = flags;
    544     return _krb5_get_cred_kdc_any(context, f, ccache,
    545 				  in_creds, NULL, NULL,
    546 				  out_creds, ret_tgts);
    547 }
    548 
    549 /**
    550  * Deprecated: use krb5_get_credentials_with_flags().
    551  *
    552  * @ingroup krb5_deprecated
    553  */
    554 
    555 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    556 krb5_get_cred_from_kdc(krb5_context context,
    557 		       krb5_ccache ccache,
    558 		       krb5_creds *in_creds,
    559 		       krb5_creds **out_creds,
    560 		       krb5_creds ***ret_tgts)
    561     KRB5_DEPRECATED_FUNCTION("Use X instead")
    562 {
    563     return krb5_get_cred_from_kdc_opt(context, ccache,
    564 				      in_creds, out_creds, ret_tgts, 0);
    565 }
    566 
    567 /**
    568  * Deprecated: use krb5_xfree().
    569  *
    570  * @ingroup krb5_deprecated
    571  */
    572 
    573 KRB5_LIB_FUNCTION void KRB5_LIB_CALL
    574 krb5_free_unparsed_name(krb5_context context, char *str)
    575     KRB5_DEPRECATED_FUNCTION("Use X instead")
    576 {
    577     krb5_xfree(str);
    578 }
    579 
    580 /**
    581  * Deprecated: use krb5_generate_subkey_extended()
    582  *
    583  * @ingroup krb5_deprecated
    584  */
    585 
    586 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    587 krb5_generate_subkey(krb5_context context,
    588 		     const krb5_keyblock *key,
    589 		     krb5_keyblock **subkey)
    590     KRB5_DEPRECATED_FUNCTION("Use X instead")
    591 {
    592     return krb5_generate_subkey_extended(context, key, ETYPE_NULL, subkey);
    593 }
    594 
    595 /**
    596  * Deprecated: use krb5_auth_con_getremoteseqnumber()
    597  *
    598  * @ingroup krb5_deprecated
    599  */
    600 
    601 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    602 krb5_auth_getremoteseqnumber(krb5_context context,
    603 			     krb5_auth_context auth_context,
    604 			     int32_t *seqnumber)
    605     KRB5_DEPRECATED_FUNCTION("Use X instead")
    606 {
    607   *seqnumber = auth_context->remote_seqnumber;
    608   return 0;
    609 }
    610 
    611 /**
    612  * Return the error message in context. On error or no error string,
    613  * the function returns NULL.
    614  *
    615  * @param context Kerberos 5 context
    616  *
    617  * @return an error string, needs to be freed with
    618  * krb5_free_error_message(). The functions return NULL on error.
    619  *
    620  * @ingroup krb5_error
    621  */
    622 
    623 KRB5_LIB_FUNCTION char * KRB5_LIB_CALL
    624 krb5_get_error_string(krb5_context context)
    625     KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead")
    626 {
    627     char *ret = NULL;
    628 
    629     HEIMDAL_MUTEX_lock(&context->mutex);
    630     if (context->error_string)
    631 	ret = strdup(context->error_string);
    632     HEIMDAL_MUTEX_unlock(&context->mutex);
    633     return ret;
    634 }
    635 
    636 KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL
    637 krb5_have_error_string(krb5_context context)
    638     KRB5_DEPRECATED_FUNCTION("Use krb5_get_error_message instead")
    639 {
    640     char *str;
    641     HEIMDAL_MUTEX_lock(&context->mutex);
    642     str = context->error_string;
    643     HEIMDAL_MUTEX_unlock(&context->mutex);
    644     return str != NULL;
    645 }
    646 
    647 struct send_to_kdc {
    648     krb5_send_to_kdc_func func;
    649     void *data;
    650 };
    651 
    652 /*
    653  * Send the data `send' to one host from `handle` and get back the reply
    654  * in `receive'.
    655  */
    656 
    657 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    658 krb5_sendto (krb5_context context,
    659 	     const krb5_data *send_data,
    660 	     krb5_krbhst_handle handle,
    661 	     krb5_data *receive)
    662 {
    663     krb5_error_code ret;
    664     krb5_sendto_ctx ctx;
    665 
    666     ret = krb5_sendto_ctx_alloc(context, &ctx);
    667     if (ret)
    668 	return ret;
    669     _krb5_sendto_ctx_set_krb5hst(context, ctx, handle);
    670 
    671     ret = krb5_sendto_context(context, ctx, send_data, (char *)_krb5_krbhst_get_realm(handle), receive);
    672     krb5_sendto_ctx_free(context, ctx);
    673     return ret;
    674 }
    675 
    676 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    677 krb5_sendto_kdc(krb5_context context,
    678 		const krb5_data *send_data,
    679 		const krb5_realm *realm,
    680 		krb5_data *receive)
    681 {
    682     return krb5_sendto_kdc_flags(context, send_data, realm, receive, 0);
    683 }
    684 
    685 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    686 krb5_sendto_kdc_flags(krb5_context context,
    687 		      const krb5_data *send_data,
    688 		      const krb5_realm *realm,
    689 		      krb5_data *receive,
    690 		      int flags)
    691 {
    692     krb5_error_code ret;
    693     krb5_sendto_ctx ctx;
    694 
    695     ret = krb5_sendto_ctx_alloc(context, &ctx);
    696     if (ret)
    697 	return ret;
    698     krb5_sendto_ctx_add_flags(ctx, flags);
    699     krb5_sendto_ctx_set_func(ctx, _krb5_kdc_retry, NULL);
    700 
    701     ret = krb5_sendto_context(context, ctx, send_data, *realm, receive);
    702     krb5_sendto_ctx_free(context, ctx);
    703     return ret;
    704 }
    705 
    706 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    707 krb5_set_send_to_kdc_func(krb5_context context,
    708 			  krb5_send_to_kdc_func func,
    709 			  void *data)
    710 {
    711     free(context->send_to_kdc);
    712     if (func == NULL) {
    713 	context->send_to_kdc = NULL;
    714 	return 0;
    715     }
    716 
    717     context->send_to_kdc = malloc(sizeof(*context->send_to_kdc));
    718     if (context->send_to_kdc == NULL) {
    719 	krb5_set_error_message(context, ENOMEM,
    720 			       N_("malloc: out of memory", ""));
    721 	return ENOMEM;
    722     }
    723 
    724     context->send_to_kdc->func = func;
    725     context->send_to_kdc->data = data;
    726     return 0;
    727 }
    728 
    729 KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
    730 _krb5_copy_send_to_kdc_func(krb5_context context, krb5_context to)
    731 {
    732     if (context->send_to_kdc)
    733 	return krb5_set_send_to_kdc_func(to,
    734 					 context->send_to_kdc->func,
    735 					 context->send_to_kdc->data);
    736     else
    737 	return krb5_set_send_to_kdc_func(to, NULL, NULL);
    738 }
    739 
    740 #endif /* HEIMDAL_SMALLER */
    741