diff options
Diffstat (limited to 'source4/heimdal/lib/krb5')
35 files changed, 1888 insertions, 741 deletions
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index b38104fc2d..004926bc89 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include <dlfcn.h> #endif -RCSID("$Id: acache.c,v 1.15 2006/03/27 04:22:23 lha Exp $"); +RCSID("$Id: acache.c,v 1.16 2006/10/19 11:41:38 lha Exp $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -113,7 +113,7 @@ init_ccapi(krb5_context context) return KRB5_CC_NOSUPP; } - init_func = dlsym(cc_handle, "cc_initialize"); + init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { krb5_set_error_string(context, "Failed to find cc_initialize" diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c index 895b01f9d8..f68be423b0 100644 --- a/source4/heimdal/lib/krb5/addr_families.c +++ b/source4/heimdal/lib/krb5/addr_families.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c,v 1.52 2006/05/05 09:26:22 lha Exp $"); +RCSID("$Id: addr_families.c,v 1.53 2006/10/22 06:54:00 lha Exp $"); struct addr_operations { int af; @@ -551,6 +551,7 @@ arange_free (krb5_context context, krb5_address *addr) a = addr->address.data; krb5_free_address(context, &a->low); krb5_free_address(context, &a->high); + krb5_data_free(&addr->address); return 0; } diff --git a/source4/heimdal/lib/krb5/asn1_glue.c b/source4/heimdal/lib/krb5/asn1_glue.c index 8f7b886e80..b07e058550 100644 --- a/source4/heimdal/lib/krb5/asn1_glue.c +++ b/source4/heimdal/lib/krb5/asn1_glue.c @@ -37,7 +37,7 @@ #include "krb5_locl.h" -RCSID("$Id: asn1_glue.c,v 1.9 2004/12/29 18:54:15 lha Exp $"); +RCSID("$Id: asn1_glue.c,v 1.10 2006/10/06 17:02:48 lha Exp $"); krb5_error_code KRB5_LIB_FUNCTION _krb5_principal2principalname (PrincipalName *p, diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index b21d42d653..a96870a7de 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: cache.c,v 1.79 2006/04/02 00:54:48 lha Exp $"); +RCSID("$Id: cache.c,v 1.82 2006/09/12 17:35:33 lha Exp $"); /* * Add a new ccache type with operations `ops', overwriting any @@ -188,7 +188,7 @@ krb5_cc_new_unique(krb5_context context, const char *type, const krb5_cc_ops *ops; if (type == NULL) - type = "FILE"; + type = KRB5_DEFAULT_CCNAME; ops = krb5_cc_get_prefix_ops(context, type); if (ops == NULL) { @@ -423,7 +423,7 @@ krb5_cc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { - return id->ops->init(context, id, primary_principal); + return (*id->ops->init)(context, id, primary_principal); } @@ -438,7 +438,7 @@ krb5_cc_destroy(krb5_context context, { krb5_error_code ret; - ret = id->ops->destroy(context, id); + ret = (*id->ops->destroy)(context, id); krb5_cc_close (context, id); return ret; } @@ -453,7 +453,7 @@ krb5_cc_close(krb5_context context, krb5_ccache id) { krb5_error_code ret; - ret = id->ops->close(context, id); + ret = (*id->ops->close)(context, id); free(id); return ret; } @@ -468,7 +468,7 @@ krb5_cc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) { - return id->ops->store(context, id, creds); + return (*id->ops->store)(context, id, creds); } /* @@ -488,8 +488,8 @@ krb5_cc_retrieve_cred(krb5_context context, krb5_cc_cursor cursor; if (id->ops->retrieve != NULL) { - return id->ops->retrieve(context, id, whichfields, - mcreds, creds); + return (*id->ops->retrieve)(context, id, whichfields, + mcreds, creds); } krb5_cc_start_seq_get(context, id, &cursor); @@ -514,7 +514,7 @@ krb5_cc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) { - return id->ops->get_princ(context, id, principal); + return (*id->ops->get_princ)(context, id, principal); } /* @@ -528,7 +528,7 @@ krb5_cc_start_seq_get (krb5_context context, const krb5_ccache id, krb5_cc_cursor *cursor) { - return id->ops->get_first(context, id, cursor); + return (*id->ops->get_first)(context, id, cursor); } /* @@ -543,7 +543,7 @@ krb5_cc_next_cred (krb5_context context, krb5_cc_cursor *cursor, krb5_creds *creds) { - return id->ops->get_next(context, id, cursor, creds); + return (*id->ops->get_next)(context, id, cursor, creds); } /* like krb5_cc_next_cred, but allow for selective retrieval */ @@ -576,7 +576,7 @@ krb5_cc_end_seq_get (krb5_context context, const krb5_ccache id, krb5_cc_cursor *cursor) { - return id->ops->end_get(context, id, cursor); + return (*id->ops->end_get)(context, id, cursor); } /* @@ -607,7 +607,7 @@ krb5_cc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) { - return id->ops->set_flags(context, id, flags); + return (*id->ops->set_flags)(context, id, flags); } /* @@ -672,7 +672,7 @@ krb5_cc_get_version(krb5_context context, const krb5_ccache id) { if(id->ops->get_version) - return id->ops->get_version(context, id); + return (*id->ops->get_version)(context, id); else return 0; } diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 594665235b..f7b3ffbf9e 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <com_err.h> -RCSID("$Id: context.c,v 1.102 2005/05/18 04:20:50 lha Exp $"); +RCSID("$Id: context.c,v 1.108 2006/10/20 22:26:10 lha Exp $"); #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ @@ -181,8 +181,8 @@ init_context_from_config_file(krb5_context context) INIT_FIELD(context, bool, srv_lookup, TRUE, "srv_lookup"); INIT_FIELD(context, bool, srv_lookup, context->srv_lookup, "dns_lookup_kdc"); INIT_FIELD(context, int, large_msg_size, 6000, "large_message_size"); + INIT_FIELD(context, bool, dns_canonicalize_hostname, TRUE, "dns_canonize_hostname"); context->default_cc_name = NULL; - INIT_FIELD(context, bool, fdns, TRUE, "fdns"); return 0; } @@ -263,7 +263,7 @@ krb5_free_context(krb5_context context) krb5_closelog(context, context->warn_dest); krb5_set_extra_addresses(context, NULL); krb5_set_ignore_addresses(context, NULL); - free(context->send_and_recv); + krb5_set_send_to_kdc_func(context, NULL, NULL); if (context->mutex != NULL) { HEIMDAL_MUTEX_destroy(context->mutex); free(context->mutex); @@ -424,13 +424,17 @@ krb5_free_config_files(char **filenames) } /* - * set `etype' to a malloced list of the default enctypes + * Returns the list of Kerberos encryption types sorted in order of + * most preferred to least preferred encryption type. The array ends + * with ETYPE_NULL. Note that some encryption types might be + * disabled, so you need to check with krb5_enctype_valid() before + * using the encryption type. */ -static krb5_error_code -default_etypes(krb5_context context, krb5_enctype **etype) +const krb5_enctype * KRB5_LIB_FUNCTION +krb5_kerberos_enctypes(krb5_context context) { - krb5_enctype p[] = { + static const krb5_enctype p[] = { ETYPE_AES256_CTS_HMAC_SHA1_96, ETYPE_AES128_CTS_HMAC_SHA1_96, ETYPE_DES3_CBC_SHA1, @@ -438,12 +442,26 @@ default_etypes(krb5_context context, krb5_enctype **etype) ETYPE_ARCFOUR_HMAC_MD5, ETYPE_DES_CBC_MD5, ETYPE_DES_CBC_MD4, - ETYPE_DES_CBC_CRC + ETYPE_DES_CBC_CRC, + ETYPE_NULL }; + return p; +} + +/* + * set `etype' to a malloced list of the default enctypes + */ + +static krb5_error_code +default_etypes(krb5_context context, krb5_enctype **etype) +{ + const krb5_enctype *p; krb5_enctype *e = NULL, *ep; int i, n = 0; - for (i = 0; i < sizeof(p)/sizeof(p[0]); i++) { + p = krb5_kerberos_enctypes(context); + + for (i = 0; p[i] != ETYPE_NULL; i++) { if (krb5_enctype_valid(context, p[i]) != 0) continue; ep = realloc(e, (n + 2) * sizeof(*e)); @@ -537,6 +555,9 @@ krb5_init_ets(krb5_context context) krb5_add_et_list(context, initialize_asn1_error_table_r); krb5_add_et_list(context, initialize_heim_error_table_r); krb5_add_et_list(context, initialize_k524_error_table_r); +#ifdef PKINIT + krb5_add_et_list(context, initialize_hx_error_table_r); +#endif } } @@ -662,3 +683,25 @@ krb5_is_thread_safe(void) return FALSE; #endif } + +void KRB5_LIB_FUNCTION +krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag) +{ + context->dns_canonicalize_hostname = flag; +} + +krb5_boolean KRB5_LIB_FUNCTION +krb5_get_dns_canonize_hostname (krb5_context context) +{ + return context->dns_canonicalize_hostname; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) +{ + if (sec) + *sec = context->kdc_sec_offset; + if (usec) + *usec = context->kdc_usec_offset; + return 0; +} diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index a3c58051f9..9f6ef6b82b 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: crypto.c,v 1.138 2006/05/08 13:47:24 lha Exp $"); +RCSID("$Id: crypto.c,v 1.145 2006/10/22 07:32:40 lha Exp $"); #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -55,7 +55,6 @@ struct krb5_crypto_data { struct key_data key; int num_key_usage; struct key_usage *key_usage; - void *params; }; #define kcrypto_oid_enc(n) { sizeof(n)/sizeof(n[0]), n } @@ -89,13 +88,9 @@ struct key_type { krb5_enctype best_etype; #endif void (*random_key)(krb5_context, krb5_keyblock*); - void (*schedule)(krb5_context, struct key_data *, const void *); + void (*schedule)(krb5_context, struct key_data *); struct salt_type *string_to_key; void (*random_to_key)(krb5_context, krb5_keyblock*, const void*, size_t); - krb5_error_code (*get_params)(krb5_context, const krb5_data *, - void **, krb5_data *); - krb5_error_code (*set_params)(krb5_context, const void *, - const krb5_data *, krb5_data *); }; struct checksum_type { @@ -181,8 +176,7 @@ krb5_DES_random_key(krb5_context context, static void krb5_DES_schedule(krb5_context context, - struct key_data *key, - const void *params) + struct key_data *key) { DES_set_key(key->key->keyvalue.data, key->schedule->data); } @@ -392,8 +386,7 @@ DES3_random_key(krb5_context context, static void DES3_schedule(krb5_context context, - struct key_data *key, - const void *params) + struct key_data *key) { DES_cblock *k = key->key->keyvalue.data; DES_key_schedule *s = key->schedule->data; @@ -546,8 +539,7 @@ DES3_random_to_key(krb5_context context, static void ARCFOUR_schedule(krb5_context context, - struct key_data *kd, - const void *params) + struct key_data *kd) { RC4_set_key (kd->schedule->data, kd->key->keyvalue.length, kd->key->keyvalue.data); @@ -618,15 +610,16 @@ AES_string_to_key(krb5_context context, if (et == NULL) return KRB5_PROG_KEYTYPE_NOSUPP; - key->keytype = enctype; - ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); - if (ret) { - krb5_set_error_string(context, "Failed to allocate pkcs5 key"); - return ret; + kd.schedule = NULL; + ALLOC(kd.key, 1); + if(kd.key == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; } - ret = krb5_copy_keyblock(context, key, &kd.key); + kd.key->keytype = enctype; + ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); if (ret) { - krb5_free_keyblock(context, key); + krb5_set_error_string(context, "Failed to allocate pkcs5 key"); return ret; } @@ -634,8 +627,8 @@ AES_string_to_key(krb5_context context, salt.saltvalue.data, salt.saltvalue.length, iter, et->keytype->size, kd.key->keyvalue.data); - kd.schedule = NULL; if (ret != 1) { + free_key_data(context, &kd); krb5_set_error_string(context, "Error calculating s2k"); return KRB5_PROG_KEYTYPE_NOSUPP; } @@ -655,8 +648,7 @@ struct krb5_aes_schedule { static void AES_schedule(krb5_context context, - struct key_data *kd, - const void *params) + struct key_data *kd) { struct krb5_aes_schedule *key = kd->schedule->data; int bits = kd->key->keyvalue.length * 8; @@ -667,115 +659,6 @@ AES_schedule(krb5_context context, } /* - * RC2 - */ - -struct _RC2_params { - int maximum_effective_key; -}; - -static krb5_error_code -rc2_get_params(krb5_context context, - const krb5_data *data, - void **params, - krb5_data *ivec) -{ - RC2CBCParameter rc2params; - struct _RC2_params *p; - krb5_error_code ret; - size_t size; - - ret = decode_RC2CBCParameter(data->data, data->length, &rc2params, &size); - if (ret) { - krb5_set_error_string(context, "Can't decode RC2 parameters"); - return ret; - } - p = malloc(sizeof(*p)); - if (p == NULL) { - free_RC2CBCParameter(&rc2params); - krb5_set_error_string(context, "malloc - out of memory"); - return ENOMEM; - } - /* XXX */ - switch(rc2params.rc2ParameterVersion) { - case 160: - p->maximum_effective_key = 40; - break; - case 120: - p->maximum_effective_key = 64; - break; - case 58: - p->maximum_effective_key = 128; - break; - - } - if (ivec) - ret = copy_octet_string(&rc2params.iv, ivec); - free_RC2CBCParameter(&rc2params); - *params = p; - - return ret; -} - -static krb5_error_code -rc2_set_params(krb5_context context, - const void *params, - const krb5_data *ivec, - krb5_data *data) -{ - RC2CBCParameter rc2params; - const struct _RC2_params *p = params; - int maximum_effective_key = 128; - krb5_error_code ret; - size_t size; - - memset(&rc2params, 0, sizeof(rc2params)); - - if (p) - maximum_effective_key = p->maximum_effective_key; - - /* XXX */ - switch(maximum_effective_key) { - case 40: - rc2params.rc2ParameterVersion = 160; - break; - case 64: - rc2params.rc2ParameterVersion = 120; - break; - case 128: - rc2params.rc2ParameterVersion = 58; - break; - } - ret = copy_octet_string(ivec, &rc2params.iv); - if (ret) - return ret; - - ASN1_MALLOC_ENCODE(RC2CBCParameter, data->data, data->length, - &rc2params, &size, ret); - if (ret == 0 && size != data->length) - krb5_abortx(context, "Internal asn1 encoder failure"); - free_RC2CBCParameter(&rc2params); - - return ret; -} - -static void -rc2_schedule(krb5_context context, - struct key_data *kd, - const void *params) -{ - const struct _RC2_params *p = params; - int maximum_effective_key = 128; - if (p) - maximum_effective_key = p->maximum_effective_key; - RC2_set_key (kd->schedule->data, - kd->key->keyvalue.length, - kd->key->keyvalue.data, - maximum_effective_key); -} - - -/* * */ @@ -898,18 +781,6 @@ static struct key_type keytype_aes128 = { AES_salt }; -static struct key_type keytype_aes192 = { - KEYTYPE_AES192, - "aes-192", - 192, - 24, - 24, - sizeof(struct krb5_aes_schedule), - NULL, - AES_schedule, - AES_salt -}; - static struct key_type keytype_aes256 = { KEYTYPE_AES256, "aes-256", @@ -934,30 +805,13 @@ static struct key_type keytype_arcfour = { arcfour_salt }; -static struct key_type keytype_rc2 = { - KEYTYPE_RC2, - "rc2", - 128, - 16, - 1, - sizeof(RC2_KEY), - NULL, - rc2_schedule, - NULL, /* XXX salt */ - NULL, - rc2_get_params, - rc2_set_params -}; - static struct key_type *keytypes[] = { &keytype_null, &keytype_des, &keytype_des3_derived, &keytype_des3, &keytype_aes128, - &keytype_aes192, &keytype_aes256, - &keytype_rc2, &keytype_arcfour }; @@ -1247,8 +1101,7 @@ krb5_generate_random_keyblock(krb5_context context, static krb5_error_code _key_schedule(krb5_context context, - struct key_data *key, - const void *params) + struct key_data *key) { krb5_error_code ret; struct encryption_type *et = _find_enctype(key->key->keytype); @@ -1269,7 +1122,7 @@ _key_schedule(krb5_context context, key->schedule = NULL; return ret; } - (*kt->schedule)(context, key, params); + (*kt->schedule)(context, key); return 0; } @@ -1933,7 +1786,7 @@ get_checksum_key(krb5_context context, *key = &crypto->key; } if(ret == 0) - ret = _key_schedule(context, *key, crypto->params); + ret = _key_schedule(context, *key); return ret; } @@ -2290,16 +2143,15 @@ DES_PCBC_encrypt_key_ivec(krb5_context context, void KRB5_LIB_FUNCTION _krb5_aes_cts_encrypt(const unsigned char *in, unsigned char *out, - size_t len, const void *aes_key, + size_t len, const AES_KEY *key, unsigned char *ivec, const int encryptp) { unsigned char tmp[AES_BLOCK_SIZE]; - const AES_KEY *key = aes_key; /* XXX remove this when we always have AES */ int i; /* * In the framework of kerberos, the length can never be shorter - * than at least one blocksize. + * then at least one blocksize. */ if (encryptp) { @@ -2838,7 +2690,7 @@ krb5_string_to_enctype(krb5_context context, } krb5_error_code KRB5_LIB_FUNCTION -krb5_enctype_to_oid(krb5_context context, +_krb5_enctype_to_oid(krb5_context context, krb5_enctype etype, heim_oid *oid) { @@ -2853,7 +2705,7 @@ krb5_enctype_to_oid(krb5_context context, return KRB5_PROG_ETYPE_NOSUPP; } krb5_clear_error_string(context); - return copy_oid(et->oid, oid); + return der_copy_oid(et->oid, oid); } krb5_error_code KRB5_LIB_FUNCTION @@ -2863,7 +2715,7 @@ _krb5_oid_to_enctype(krb5_context context, { int i; for(i = 0; i < num_etypes; i++) { - if(etypes[i]->oid && heim_oid_cmp(etypes[i]->oid, oid) == 0) { + if(etypes[i]->oid && der_heim_oid_cmp(etypes[i]->oid, oid) == 0) { *etype = etypes[i]->type; return 0; } @@ -3080,7 +2932,7 @@ encrypt_internal_derived(krb5_context context, ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) goto fail; - ret = _key_schedule(context, dkey, crypto->params); + ret = _key_schedule(context, dkey); if(ret) goto fail; #ifdef CRYPTO_DEBUG @@ -3146,7 +2998,7 @@ encrypt_internal(krb5_context context, goto fail; memcpy(p + et->confoundersize, cksum.checksum.data, cksum.checksum.length); free_Checksum(&cksum); - ret = _key_schedule(context, &crypto->key, crypto->params); + ret = _key_schedule(context, &crypto->key); if(ret) goto fail; #ifdef CRYPTO_DEBUG @@ -3246,7 +3098,7 @@ decrypt_internal_derived(krb5_context context, free(p); return ret; } - ret = _key_schedule(context, dkey, crypto->params); + ret = _key_schedule(context, dkey); if(ret) { free(p); return ret; @@ -3313,7 +3165,7 @@ decrypt_internal(krb5_context context, } memcpy(p, data, len); - ret = _key_schedule(context, &crypto->key, crypto->params); + ret = _key_schedule(context, &crypto->key); if(ret) { free(p); return ret; @@ -3613,11 +3465,9 @@ derive_key(krb5_context context, unsigned char *k; unsigned int nblocks = 0, i; krb5_error_code ret = 0; - struct key_type *kt = et->keytype; - /* since RC2 is only the weird crypto alg with parameter and this - * function not defined with work with RC2, this is ok */ - ret = _key_schedule(context, key, NULL); + + ret = _key_schedule(context, key); if(ret) return ret; if(et->blocksize * 8 < kt->bits || @@ -3795,7 +3645,6 @@ krb5_crypto_init(krb5_context context, (*crypto)->key.schedule = NULL; (*crypto)->num_key_usage = 0; (*crypto)->key_usage = NULL; - (*crypto)->params = NULL; return 0; } @@ -3825,80 +3674,11 @@ krb5_crypto_destroy(krb5_context context, free_key_usage(context, &crypto->key_usage[i]); free(crypto->key_usage); free_key_data(context, &crypto->key); - free(crypto->params); free (crypto); return 0; } krb5_error_code KRB5_LIB_FUNCTION -krb5_crypto_get_params(krb5_context context, - const krb5_crypto crypto, - const krb5_data *params, - krb5_data *ivec) -{ - krb5_error_code (*gp)(krb5_context, const krb5_data *,void **,krb5_data *); - krb5_error_code ret; - - gp = crypto->et->keytype->get_params; - if (gp) { - if (crypto->params) { - krb5_set_error_string(context, - "krb5_crypto_get_params called " - "more than once"); - return KRB5_PROG_ETYPE_NOSUPP; - } - ret = (*gp)(context, params, &crypto->params, ivec); - } else { - size_t size; - if (ivec == NULL) - return 0; - ret = decode_CBCParameter(params->data, params->length, ivec, &size); - } - if (ret) - return ret; - if (ivec->length < crypto->et->blocksize) { - krb5_data_free(ivec); - krb5_set_error_string(context, "%s IV of wrong size", - crypto->et->name); - return ASN1_PARSE_ERROR; - } - return 0; -} - -krb5_error_code KRB5_LIB_FUNCTION -krb5_crypto_set_params(krb5_context context, - const krb5_crypto crypto, - const krb5_data *ivec, - krb5_data *params) -{ - krb5_error_code (*sp)(krb5_context, const void *, - const krb5_data *, krb5_data *); - krb5_error_code ret; - - sp = crypto->et->keytype->set_params; - if (sp == NULL) { - size_t size; - if (ivec == NULL) - return 0; - ASN1_MALLOC_ENCODE(CBCParameter, params->data, params->length, - ivec, &size, ret); - if (ret) - return ret; - if (size != params->length) - krb5_abortx(context, "Internal asn1 encoder failure"); - return 0; - } - if (crypto->params) { - krb5_set_error_string(context, - "krb5_crypto_set_params called " - "more than once"); - return KRB5_PROG_ETYPE_NOSUPP; - } - return (*sp)(context, crypto->params, ivec, params); -} - - -krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getblocksize(krb5_context context, krb5_crypto crypto, size_t *blocksize) diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index 3192c4c64f..f0c6d00abe 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: data.c,v 1.20 2006/04/02 01:06:07 lha Exp $"); +RCSID("$Id: data.c,v 1.21 2006/10/14 09:45:41 lha Exp $"); void KRB5_LIB_FUNCTION krb5_data_zero(krb5_data *p) @@ -110,7 +110,7 @@ krb5_copy_data(krb5_context context, krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - ret = copy_octet_string(indata, *outdata); + ret = der_copy_octet_string(indata, *outdata); if(ret) { krb5_clear_error_string (context); free(*outdata); diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c index f03bf15807..4d0692bcfa 100644 --- a/source4/heimdal/lib/krb5/expand_hostname.c +++ b/source4/heimdal/lib/krb5/expand_hostname.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: expand_hostname.c,v 1.12 2004/05/25 21:24:14 lha Exp $"); +RCSID("$Id: expand_hostname.c,v 1.13 2006/10/17 09:16:32 lha Exp $"); static krb5_error_code copy_hostname(krb5_context context, @@ -62,13 +62,12 @@ krb5_expand_hostname (krb5_context context, struct addrinfo *ai, *a, hints; int error; + if (!context->dns_canonicalize_hostname) + return copy_hostname (context, orig_hostname, new_hostname); + memset (&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; - if (!context->fdns) { - return copy_hostname (context, orig_hostname, new_hostname); - } - error = getaddrinfo (orig_hostname, NULL, &hints, &ai); if (error) return copy_hostname (context, orig_hostname, new_hostname); @@ -128,10 +127,9 @@ krb5_expand_hostname_realms (krb5_context context, int error; krb5_error_code ret = 0; - if (!context->fdns) { + if (!context->dns_canonicalize_hostname) return vanilla_hostname (context, orig_hostname, new_hostname, realms); - } memset (&hints, 0, sizeof(hints)); hints.ai_flags = AI_CANONNAME; diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 1fa3f9143e..b404c30f6e 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_cred.c,v 1.109 2006/02/03 11:41:02 lha Exp $"); +RCSID("$Id: get_cred.c,v 1.112 2006/06/06 21:22:54 lha Exp $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -142,6 +142,7 @@ init_tgs_req (krb5_context context, krb5_creds *in_creds, krb5_creds *krbtgt, unsigned nonce, + const METHOD_DATA *padata, krb5_keyblock **subkey, TGS_REQ *t, krb5_key_usage usage) @@ -220,12 +221,22 @@ init_tgs_req (krb5_context context, krb5_set_error_string(context, "malloc: out of memory"); goto fail; } - ALLOC_SEQ(t->padata, 1); + ALLOC_SEQ(t->padata, 1 + padata->len); if (t->padata->val == NULL) { ret = ENOMEM; krb5_set_error_string(context, "malloc: out of memory"); goto fail; } + { + int i; + for (i = 0; i < padata->len; i++) { + ret = copy_PA_DATA(&padata->val[i], &t->padata->val[i + 1]); + if (ret) { + krb5_set_error_string(context, "malloc: out of memory"); + goto fail; + } + } + } { krb5_auth_context ac; @@ -268,7 +279,7 @@ init_tgs_req (krb5_context context, ret = make_pa_tgs_req(context, ac, &t->req_body, - t->padata->val, + &t->padata->val[0], krbtgt, usage); if(ret) { @@ -383,8 +394,10 @@ get_cred_kdc_usage(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, krb5_addresses *addresses, - krb5_creds *in_creds, + krb5_creds *in_creds, krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, krb5_creds *out_creds, krb5_key_usage usage) { @@ -397,36 +410,91 @@ get_cred_kdc_usage(krb5_context context, unsigned nonce; krb5_keyblock *subkey = NULL; size_t len; - Ticket second_ticket; + Ticket second_ticket_data; int send_to_kdc_flags = 0; + METHOD_DATA padata; krb5_data_zero(&resp); krb5_data_zero(&enc); + padata.val = NULL; + padata.len = 0; krb5_generate_random_block(&nonce, sizeof(nonce)); nonce &= 0xffffffff; - if(flags.b.enc_tkt_in_skey){ + if(flags.b.enc_tkt_in_skey && second_ticket == NULL){ ret = decode_Ticket(in_creds->second_ticket.data, in_creds->second_ticket.length, - &second_ticket, &len); + &second_ticket_data, &len); if(ret) return ret; + second_ticket = &second_ticket_data; + } + + + if (impersonate_principal) { + krb5_crypto crypto; + PA_S4U2Self self; + krb5_data data; + void *buf; + size_t size; + + self.name = impersonate_principal->name; + self.realm = impersonate_principal->realm; + self.auth = estrdup("Kerberos"); + + ret = _krb5_s4u2self_to_checksumdata(context, &self, &data); + if (ret) { + free(self.auth); + goto out; + } + + ret = krb5_crypto_init(context, &krbtgt->session, 0, &crypto); + if (ret) { + free(self.auth); + krb5_data_free(&data); + goto out; + } + + ret = krb5_create_checksum(context, + crypto, + KRB5_KU_TGS_IMPERSONATE, + 0, + data.data, + data.length, + &self.cksum); + krb5_crypto_destroy(context, crypto); + krb5_data_free(&data); + if (ret) { + free(self.auth); + goto out; + } + + ASN1_MALLOC_ENCODE(PA_S4U2Self, buf, len, &self, &size, ret); + free(self.auth); + free_Checksum(&self.cksum); + if (ret) + goto out; + if (len != size) + krb5_abortx(context, "internal asn1 error"); + + ret = krb5_padata_add(context, &padata, KRB5_PADATA_S4U2SELF, buf, len); + if (ret) + goto out; } ret = init_tgs_req (context, id, addresses, flags, - flags.b.enc_tkt_in_skey ? &second_ticket : NULL, + second_ticket, in_creds, krbtgt, nonce, + &padata, &subkey, &req, usage); - if(flags.b.enc_tkt_in_skey) - free_Ticket(&second_ticket); if (ret) goto out; @@ -475,7 +543,7 @@ again: &krbtgt->addresses, nonce, TRUE, - flags.b.request_anonymous, + TRUE /* flags.b.request_anonymous */, decrypt_tkt_with_subkey, subkey); krb5_free_kdc_rep(context, &rep); @@ -497,6 +565,9 @@ again: } out: + if (second_ticket == &second_ticket_data) + free_Ticket(&second_ticket_data); + free_METHOD_DATA(&padata); krb5_data_free(&resp); krb5_data_free(&enc); if(subkey){ @@ -514,16 +585,20 @@ get_cred_kdc(krb5_context context, krb5_addresses *addresses, krb5_creds *in_creds, krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, krb5_creds *out_creds) { krb5_error_code ret; ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, out_creds, KRB5_KU_TGS_REQ_AUTH); + krbtgt, impersonate_principal, second_ticket, + out_creds, KRB5_KU_TGS_REQ_AUTH); if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { krb5_clear_error_string (context); ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, out_creds, KRB5_KU_AP_REQ_AUTH); + krbtgt, impersonate_principal, second_ticket, + out_creds, KRB5_KU_AP_REQ_AUTH); } return ret; } @@ -533,6 +608,7 @@ get_cred_kdc(krb5_context context, static krb5_error_code get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, krb5_creds *in_creds, krb5_creds *krbtgt, + krb5_principal impersonate_principal, Ticket *second_ticket, krb5_creds *out_creds) { krb5_error_code ret; @@ -543,7 +619,8 @@ get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, if(addresses.len == 0) addrs = NULL; ret = get_cred_kdc(context, id, flags, addrs, - in_creds, krbtgt, out_creds); + in_creds, krbtgt, impersonate_principal, second_ticket, + out_creds); krb5_free_addresses(context, &addresses); return ret; } @@ -575,7 +652,7 @@ krb5_get_kdc_cred(krb5_context context, return ret; } ret = get_cred_kdc(context, id, flags, addresses, - in_creds, krbtgt, *out_creds); + in_creds, krbtgt, NULL, NULL, *out_creds); krb5_free_creds (context, krbtgt); if(ret) free(*out_creds); @@ -607,7 +684,17 @@ find_cred(krb5_context context, } tgts++; } - krb5_clear_error_string(context); + { + char *str; + ret = krb5_unparse_name(context, server, &str); + if(ret == 0) { + krb5_set_error_string(context, "Matching credential " + "(%s) not found", str); + free(str); + } else { + krb5_clear_error_string(context); + } + } return KRB5_CC_NOTFOUND; } @@ -650,6 +737,8 @@ get_cred_from_kdc_flags(krb5_context context, krb5_kdc_flags flags, krb5_ccache ccache, krb5_creds *in_creds, + krb5_principal impersonate_principal, + Ticket *second_ticket, krb5_creds **out_creds, krb5_creds ***ret_tgts) { @@ -707,10 +796,16 @@ get_cred_from_kdc_flags(krb5_context context, if (noaddr) ret = get_cred_kdc(context, ccache, flags, NULL, - in_creds, &tgts, *out_creds); + in_creds, &tgts, + impersonate_principal, + second_ticket, + *out_creds); else ret = get_cred_kdc_la(context, ccache, flags, - in_creds, &tgts, *out_creds); + in_creds, &tgts, + impersonate_principal, + second_ticket, + *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -731,7 +826,7 @@ get_cred_from_kdc_flags(krb5_context context, heim_general_string tgt_inst; ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds, - &tgt, ret_tgts); + NULL, NULL, &tgt, ret_tgts); if(ret) { krb5_free_principal(context, tmp_creds.server); krb5_free_principal(context, tmp_creds.client); @@ -776,10 +871,12 @@ get_cred_from_kdc_flags(krb5_context context, &noaddr); if (noaddr) ret = get_cred_kdc (context, ccache, flags, NULL, - in_creds, tgt, *out_creds); + in_creds, tgt, NULL, NULL, + *out_creds); else ret = get_cred_kdc_la(context, ccache, flags, - in_creds, tgt, *out_creds); + in_creds, tgt, NULL, NULL, + *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -800,7 +897,8 @@ krb5_get_cred_from_kdc_opt(krb5_context context, krb5_kdc_flags f; f.i = flags; return get_cred_from_kdc_flags(context, f, ccache, - in_creds, out_creds, ret_tgts); + in_creds, NULL, NULL, + out_creds, ret_tgts); } krb5_error_code KRB5_LIB_FUNCTION @@ -879,15 +977,18 @@ krb5_get_credentials_with_flags(krb5_context context, } if(options & KRB5_GC_USER_USER) flags.b.enc_tkt_in_skey = 1; + if (flags.b.enc_tkt_in_skey) + options |= KRB5_GC_NO_STORE; + tgts = NULL; ret = get_cred_from_kdc_flags(context, flags, ccache, - in_creds, out_creds, &tgts); + in_creds, NULL, NULL, out_creds, &tgts); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); krb5_free_creds(context, tgts[i]); } free(tgts); - if(ret == 0 && flags.b.enc_tkt_in_skey == 0) + if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0) krb5_cc_store_cred(context, ccache, *out_creds); return ret; } @@ -904,3 +1005,200 @@ krb5_get_credentials(krb5_context context, return krb5_get_credentials_with_flags(context, options, flags, ccache, in_creds, out_creds); } + +struct krb5_get_creds_opt_data { + krb5_principal self; + krb5_flags options; + krb5_enctype enctype; + Ticket *ticket; +}; + + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_alloc(krb5_context context, krb5_get_creds_opt *opt) +{ + *opt = calloc(1, sizeof(**opt)); + if (*opt == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_free(krb5_context context, krb5_get_creds_opt opt) +{ + if (opt->self) + krb5_free_principal(context, opt->self); + memset(opt, 0, sizeof(*opt)); + free(opt); +} + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_options(krb5_context context, + krb5_get_creds_opt opt, + krb5_flags options) +{ + opt->options = options; +} + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_add_options(krb5_context context, + krb5_get_creds_opt opt, + krb5_flags options) +{ + opt->options |= options; +} + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_enctype(krb5_context context, + krb5_get_creds_opt opt, + krb5_enctype enctype) +{ + opt->enctype = enctype; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_impersonate(krb5_context context, + krb5_get_creds_opt opt, + krb5_const_principal self) +{ + if (opt->self) + krb5_free_principal(context, opt->self); + return krb5_copy_principal(context, self, &opt->self); +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_ticket(krb5_context context, + krb5_get_creds_opt opt, + const Ticket *ticket) +{ + if (opt->ticket) { + free_Ticket(opt->ticket); + free(opt->ticket); + opt->ticket = NULL; + } + if (ticket) { + krb5_error_code ret; + + opt->ticket = malloc(sizeof(*ticket)); + if (opt->ticket == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + ret = copy_Ticket(ticket, opt->ticket); + if (ret) { + free(opt->ticket); + opt->ticket = NULL; + krb5_set_error_string(context, "malloc: out of memory"); + return ret; + } + } + return 0; +} + + + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds(krb5_context context, + krb5_get_creds_opt opt, + krb5_ccache ccache, + krb5_const_principal inprinc, + krb5_creds **out_creds) +{ + krb5_kdc_flags flags; + krb5_flags options; + krb5_creds in_creds; + krb5_error_code ret; + krb5_creds **tgts; + krb5_creds *res_creds; + int i; + + memset(&in_creds, 0, sizeof(in_creds)); + in_creds.server = rk_UNCONST(inprinc); + + ret = krb5_cc_get_principal(context, ccache, &in_creds.client); + if (ret) + return ret; + + options = opt->options; + flags.i = 0; + + *out_creds = NULL; + res_creds = calloc(1, sizeof(*res_creds)); + if (res_creds == NULL) { + krb5_free_principal(context, in_creds.client); + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + + if (opt->enctype) { + in_creds.session.keytype = opt->enctype; + options |= KRB5_TC_MATCH_KEYTYPE; + } + + /* + * If we got a credential, check if credential is expired before + * returning it. + */ + ret = krb5_cc_retrieve_cred(context, + ccache, + opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0, + &in_creds, res_creds); + /* + * If we got a credential, check if credential is expired before + * returning it, but only if KRB5_GC_EXPIRED_OK is not set. + */ + if (ret == 0) { + krb5_timestamp timeret; + + /* If expired ok, don't bother checking */ + if(options & KRB5_GC_EXPIRED_OK) { + *out_creds = res_creds; + krb5_free_principal(context, in_creds.client); + return 0; + } + + krb5_timeofday(context, &timeret); + if(res_creds->times.endtime > timeret) { + *out_creds = res_creds; + krb5_free_principal(context, in_creds.client); + return 0; + } + if(options & KRB5_GC_CACHED) + krb5_cc_remove_cred(context, ccache, 0, res_creds); + + } else if(ret != KRB5_CC_END) { + free(res_creds); + krb5_free_principal(context, in_creds.client); + return ret; + } + free(res_creds); + if(options & KRB5_GC_CACHED) { + krb5_clear_error_string (context); + krb5_free_principal(context, in_creds.client); + return KRB5_CC_NOTFOUND; + } + if(options & KRB5_GC_USER_USER) { + flags.b.enc_tkt_in_skey = 1; + options |= KRB5_GC_NO_STORE; + } + if (options & KRB5_GC_FORWARDABLE) + flags.b.forwardable = 1; + if (options & KRB5_GC_NO_TRANSIT_CHECK) + flags.b.disable_transited_check = 1; + + tgts = NULL; + ret = get_cred_from_kdc_flags(context, flags, ccache, + &in_creds, opt->self, opt->ticket, + out_creds, &tgts); + krb5_free_principal(context, in_creds.client); + for(i = 0; tgts && tgts[i]; i++) { + krb5_cc_store_cred(context, ccache, tgts[i]); + krb5_free_creds(context, tgts[i]); + } + free(tgts); + if(ret == 0 && (options & KRB5_GC_NO_STORE) == 0) + krb5_cc_store_cred(context, ccache, *out_creds); + return ret; +} diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index f042cdb573..661d05663b 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -376,7 +376,7 @@ krb5_get_forwarded_creds (krb5_context context, cred.enc_part.cipher.length = buf_size; } else { /* - * Here older versions than 0.7.2 of Heimdal used the local or + * Here older versions then 0.7.2 of Heimdal used the local or * remote subkey. That is wrong, the session key should be * used. Heimdal 0.7.2 and newer have code to try both in the * receiving end. diff --git a/source4/heimdal/lib/krb5/get_host_realm.c b/source4/heimdal/lib/krb5/get_host_realm.c index 33a3438b12..ffc646d98b 100644 --- a/source4/heimdal/lib/krb5/get_host_realm.c +++ b/source4/heimdal/lib/krb5/get_host_realm.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <resolve.h> -RCSID("$Id: get_host_realm.c,v 1.35 2005/08/23 08:14:02 lha Exp $"); +RCSID("$Id: get_host_realm.c,v 1.37 2006/10/17 19:28:36 lha Exp $"); /* To automagically find the correct realm of a host (without * [domain_realm] in krb5.conf) add a text record for your domain with @@ -187,65 +187,71 @@ _krb5_get_host_realm_int (krb5_context context, return 0; } } - - *realms = malloc(2 * sizeof(krb5_realm)); - if (*realms == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } - - (*realms)[1] = NULL; - p = strchr(host, '.'); if(p != NULL) { p++; - (*realms)[0] = strdup(p); - if((*realms)[0] == NULL) { - free(*realms); + *realms = malloc(2 * sizeof(krb5_realm)); + if (*realms == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - strupr((*realms)[0]); - } else { - krb5_error_code ret; - ret = krb5_get_default_realm(context, &(*realms)[0]); - if(ret) { + + (*realms)[0] = strdup(p); + if((*realms)[0] == NULL) { free(*realms); krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - if((*realms)[0] == NULL) { - free(*realms); - krb5_set_error_string(context, "unable to find realm of host %s", host); - return KRB5_ERR_HOST_REALM_UNKNOWN; - } + strupr((*realms)[0]); + (*realms)[1] = NULL; + return 0; } - return 0; + krb5_set_error_string(context, "unable to find realm of host %s", host); + return KRB5_ERR_HOST_REALM_UNKNOWN; } /* - * Return the realm(s) of `host' as a NULL-terminated list in `realms'. + * Return the realm(s) of `host' as a NULL-terminated list in + * `realms'. Free `realms' with krb5_free_host_realm(). */ krb5_error_code KRB5_LIB_FUNCTION krb5_get_host_realm(krb5_context context, - const char *host, + const char *targethost, krb5_realm **realms) { + const char *host = targethost; char hostname[MAXHOSTNAMELEN]; - krb5_boolean use_dns; + krb5_error_code ret; + int use_dns; if (host == NULL) { - if (gethostname (hostname, sizeof(hostname))) + if (gethostname (hostname, sizeof(hostname))) { + *realms = NULL; return errno; + } host = hostname; } - if (strchr(host, '.') == NULL) { - use_dns = FALSE; - } else { - use_dns = TRUE; - } + /* + * If our local hostname is without components, don't even try to dns. + */ + + use_dns = (strchr(host, '.') != NULL); - return _krb5_get_host_realm_int (context, host, use_dns, realms); + ret = _krb5_get_host_realm_int (context, host, use_dns, realms); + if (ret && targethost != NULL) { + /* + * If there was no realm mapping for the host (and we wasn't + * looking for ourself), guess at the local realm, maybe our + * KDC knows better then we do and we get a referral back. + */ + ret = krb5_get_default_realms(context, realms); + if (ret) { + krb5_set_error_string(context, "Unable to find realm of host %s", + host); + return KRB5_ERR_HOST_REALM_UNKNOWN; + } + } + return ret; } diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index 5c488d1ddc..ebc96f2279 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_in_tkt.c,v 1.116 2005/06/15 02:53:20 lha Exp $"); +RCSID("$Id: get_in_tkt.c,v 1.119 2006/10/06 17:05:08 lha Exp $"); krb5_error_code KRB5_LIB_FUNCTION krb5_init_etype (krb5_context context, @@ -137,7 +137,7 @@ _krb5_extract_ticket(krb5_context context, time_t tmp_time; krb5_timestamp sec_now; - ret = _krb5_principalname2krb5_principal (context, + ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.cname, rep->kdc_rep.crealm); @@ -171,7 +171,7 @@ _krb5_extract_ticket(krb5_context context, /* compare server */ - ret = _krb5_principalname2krb5_principal (context, + ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.ticket.sname, rep->kdc_rep.ticket.realm); @@ -411,7 +411,7 @@ add_padata(krb5_context context, static krb5_error_code init_as_req (krb5_context context, - krb5_kdc_flags opts, + KDCOptions opts, krb5_creds *creds, const krb5_addresses *addrs, const krb5_enctype *etypes, @@ -429,7 +429,7 @@ init_as_req (krb5_context context, a->pvno = 5; a->msg_type = krb_as_req; - a->req_body.kdc_options = opts.b; + a->req_body.kdc_options = opts; a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; @@ -649,14 +649,14 @@ krb5_get_in_cred(krb5_context context, krb5_salt salt; krb5_keyblock *key; size_t size; - krb5_kdc_flags opts; + KDCOptions opts; PA_DATA *pa; krb5_enctype etype; krb5_preauthdata *my_preauth = NULL; unsigned nonce; int done; - opts.i = options; + opts = int2KDCOptions(options); krb5_generate_random_block (&nonce, sizeof(nonce)); nonce &= 0xffffffff; @@ -771,7 +771,7 @@ krb5_get_in_cred(krb5_context context, NULL, nonce, FALSE, - opts.b.request_anonymous, + opts.request_anonymous, decrypt_proc, decryptarg); memset (key->keyvalue.data, 0, key->keyvalue.length); @@ -801,12 +801,9 @@ krb5_get_in_tkt(krb5_context context, krb5_kdc_rep *ret_as_reply) { krb5_error_code ret; - krb5_kdc_flags opts; - opts.i = 0; - opts.b = int2KDCOptions(options); ret = krb5_get_in_cred (context, - opts.i, + options, addrs, etypes, ptypes, diff --git a/source4/heimdal/lib/krb5/heim_err.c b/source4/heimdal/lib/krb5/heim_err.c new file mode 100644 index 0000000000..f72a265ba9 --- /dev/null +++ b/source4/heimdal/lib/krb5/heim_err.c @@ -0,0 +1,162 @@ +/* Generated from heim_err.et */ +/* $Id: heim_err.et,v 1.13 2004/02/13 16:23:40 lha Exp $ */ + +#include <stddef.h> +#include <com_err.h> +#include "heim_err.h" + +static const char *heim_error_strings[] = { + /* 000 */ "Error parsing log destination", + /* 001 */ "Failed to convert v4 principal", + /* 002 */ "Salt type is not supported by enctype", + /* 003 */ "Host not found", + /* 004 */ "Operation not supported", + /* 005 */ "End of file", + /* 006 */ "Failed to get the master key", + /* 007 */ "Unacceptable service used", + /* 008 */ "Reserved heim error (8)", + /* 009 */ "Reserved heim error (9)", + /* 010 */ "Reserved heim error (10)", + /* 011 */ "Reserved heim error (11)", + /* 012 */ "Reserved heim error (12)", + /* 013 */ "Reserved heim error (13)", + /* 014 */ "Reserved heim error (14)", + /* 015 */ "Reserved heim error (15)", + /* 016 */ "Reserved heim error (16)", + /* 017 */ "Reserved heim error (17)", + /* 018 */ "Reserved heim error (18)", + /* 019 */ "Reserved heim error (19)", + /* 020 */ "Reserved heim error (20)", + /* 021 */ "Reserved heim error (21)", + /* 022 */ "Reserved heim error (22)", + /* 023 */ "Reserved heim error (23)", + /* 024 */ "Reserved heim error (24)", + /* 025 */ "Reserved heim error (25)", + /* 026 */ "Reserved heim error (26)", + /* 027 */ "Reserved heim error (27)", + /* 028 */ "Reserved heim error (28)", + /* 029 */ "Reserved heim error (29)", + /* 030 */ "Reserved heim error (30)", + /* 031 */ "Reserved heim error (31)", + /* 032 */ "Reserved heim error (32)", + /* 033 */ "Reserved heim error (33)", + /* 034 */ "Reserved heim error (34)", + /* 035 */ "Reserved heim error (35)", + /* 036 */ "Reserved heim error (36)", + /* 037 */ "Reserved heim error (37)", + /* 038 */ "Reserved heim error (38)", + /* 039 */ "Reserved heim error (39)", + /* 040 */ "Reserved heim error (40)", + /* 041 */ "Reserved heim error (41)", + /* 042 */ "Reserved heim error (42)", + /* 043 */ "Reserved heim error (43)", + /* 044 */ "Reserved heim error (44)", + /* 045 */ "Reserved heim error (45)", + /* 046 */ "Reserved heim error (46)", + /* 047 */ "Reserved heim error (47)", + /* 048 */ "Reserved heim error (48)", + /* 049 */ "Reserved heim error (49)", + /* 050 */ "Reserved heim error (50)", + /* 051 */ "Reserved heim error (51)", + /* 052 */ "Reserved heim error (52)", + /* 053 */ "Reserved heim error (53)", + /* 054 */ "Reserved heim error (54)", + /* 055 */ "Reserved heim error (55)", + /* 056 */ "Reserved heim error (56)", + /* 057 */ "Reserved heim error (57)", + /* 058 */ "Reserved heim error (58)", + /* 059 */ "Reserved heim error (59)", + /* 060 */ "Reserved heim error (60)", + /* 061 */ "Reserved heim error (61)", + /* 062 */ "Reserved heim error (62)", + /* 063 */ "Reserved heim error (63)", + /* 064 */ "Certificate missing", + /* 065 */ "Private key missing", + /* 066 */ "No valid certificate authority", + /* 067 */ "Certificate invalid", + /* 068 */ "Private key invalid", + /* 069 */ "Reserved heim error (69)", + /* 070 */ "Reserved heim error (70)", + /* 071 */ "Reserved heim error (71)", + /* 072 */ "Reserved heim error (72)", + /* 073 */ "Reserved heim error (73)", + /* 074 */ "Reserved heim error (74)", + /* 075 */ "Reserved heim error (75)", + /* 076 */ "Reserved heim error (76)", + /* 077 */ "Reserved heim error (77)", + /* 078 */ "Reserved heim error (78)", + /* 079 */ "Reserved heim error (79)", + /* 080 */ "Reserved heim error (80)", + /* 081 */ "Reserved heim error (81)", + /* 082 */ "Reserved heim error (82)", + /* 083 */ "Reserved heim error (83)", + /* 084 */ "Reserved heim error (84)", + /* 085 */ "Reserved heim error (85)", + /* 086 */ "Reserved heim error (86)", + /* 087 */ "Reserved heim error (87)", + /* 088 */ "Reserved heim error (88)", + /* 089 */ "Reserved heim error (89)", + /* 090 */ "Reserved heim error (90)", + /* 091 */ "Reserved heim error (91)", + /* 092 */ "Reserved heim error (92)", + /* 093 */ "Reserved heim error (93)", + /* 094 */ "Reserved heim error (94)", + /* 095 */ "Reserved heim error (95)", + /* 096 */ "Reserved heim error (96)", + /* 097 */ "Reserved heim error (97)", + /* 098 */ "Reserved heim error (98)", + /* 099 */ "Reserved heim error (99)", + /* 100 */ "Reserved heim error (100)", + /* 101 */ "Reserved heim error (101)", + /* 102 */ "Reserved heim error (102)", + /* 103 */ "Reserved heim error (103)", + /* 104 */ "Reserved heim error (104)", + /* 105 */ "Reserved heim error (105)", + /* 106 */ "Reserved heim error (106)", + /* 107 */ "Reserved heim error (107)", + /* 108 */ "Reserved heim error (108)", + /* 109 */ "Reserved heim error (109)", + /* 110 */ "Reserved heim error (110)", + /* 111 */ "Reserved heim error (111)", + /* 112 */ "Reserved heim error (112)", + /* 113 */ "Reserved heim error (113)", + /* 114 */ "Reserved heim error (114)", + /* 115 */ "Reserved heim error (115)", + /* 116 */ "Reserved heim error (116)", + /* 117 */ "Reserved heim error (117)", + /* 118 */ "Reserved heim error (118)", + /* 119 */ "Reserved heim error (119)", + /* 120 */ "Reserved heim error (120)", + /* 121 */ "Reserved heim error (121)", + /* 122 */ "Reserved heim error (122)", + /* 123 */ "Reserved heim error (123)", + /* 124 */ "Reserved heim error (124)", + /* 125 */ "Reserved heim error (125)", + /* 126 */ "Reserved heim error (126)", + /* 127 */ "Reserved heim error (127)", + /* 128 */ "unknown error from getaddrinfo", + /* 129 */ "address family for nodename not supported", + /* 130 */ "temporary failure in name resolution", + /* 131 */ "invalid value for ai_flags", + /* 132 */ "non-recoverable failure in name resolution", + /* 133 */ "ai_family not supported", + /* 134 */ "memory allocation failure", + /* 135 */ "no address associated with nodename", + /* 136 */ "nodename nor servname provided, or not known", + /* 137 */ "servname not supported for ai_socktype", + /* 138 */ "ai_socktype not supported", + /* 139 */ "system error returned in errno", + NULL +}; + +#define num_errors 140 + +void initialize_heim_error_table_r(struct et_list **list) +{ + initialize_error_table_r(list, heim_error_strings, num_errors, ERROR_TABLE_BASE_heim); +} + +void initialize_heim_error_table(void) +{ + init_error_table(heim_error_strings, ERROR_TABLE_BASE_heim, num_errors); +} diff --git a/source4/heimdal/lib/krb5/heim_threads.h b/source4/heimdal/lib/krb5/heim_threads.h index 41f0f83306..3ebe66beee 100755 --- a/source4/heimdal/lib/krb5/heim_threads.h +++ b/source4/heimdal/lib/krb5/heim_threads.h @@ -53,7 +53,7 @@ /* * NetBSD have a thread lib that we can use that part of libc that * works regardless if application are linked to pthreads or not. - * NetBSD newer than 2.99.11 just use pthread.h, and the same thing + * NetBSD newer then 2.99.11 just use pthread.h, and the same thing * will happen. */ #include <threadlib.h> diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c index 88de280a00..6dacb316d8 100644 --- a/source4/heimdal/lib/krb5/init_creds.c +++ b/source4/heimdal/lib/krb5/init_creds.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds.c,v 1.23 2006/04/02 01:08:30 lha Exp $"); +RCSID("$Id: init_creds.c,v 1.28 2006/09/04 14:28:54 lha Exp $"); void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) @@ -97,6 +97,39 @@ _krb5_get_init_creds_opt_copy(krb5_context context, } void KRB5_LIB_FUNCTION +_krb5_get_init_creds_opt_free_krb5_error(krb5_get_init_creds_opt *opt) +{ + if (opt->opt_private == NULL || opt->opt_private->error == NULL) + return; + free_KRB_ERROR(opt->opt_private->error); + free(opt->opt_private->error); + opt->opt_private->error = NULL; +} + +void KRB5_LIB_FUNCTION +_krb5_get_init_creds_opt_set_krb5_error(krb5_context context, + krb5_get_init_creds_opt *opt, + const KRB_ERROR *error) +{ + krb5_error_code ret; + + if (opt->opt_private == NULL) + return; + + _krb5_get_init_creds_opt_free_krb5_error(opt); + + opt->opt_private->error = malloc(sizeof(*opt->opt_private->error)); + if (opt->opt_private->error == NULL) + return; + ret = copy_KRB_ERROR(error, opt->opt_private->error); + if (ret) { + free(opt->opt_private->error); + opt->opt_private->error = NULL; + } +} + + +void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt) { if (opt->opt_private == NULL) @@ -104,6 +137,7 @@ krb5_get_init_creds_opt_free(krb5_get_init_creds_opt *opt) if (opt->opt_private->refcount < 1) /* abort ? */ return; if (--opt->opt_private->refcount == 0) { + _krb5_get_init_creds_opt_free_krb5_error(opt); _krb5_get_init_creds_opt_free_pkinit(opt); free(opt->opt_private); } @@ -160,8 +194,6 @@ get_config_bool (krb5_context context, * [realms] or [libdefaults] for some of the values. */ -static krb5_addresses no_addrs = {0, NULL}; - void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_set_default_flags(krb5_context context, const char *appname, @@ -192,9 +224,9 @@ krb5_get_init_creds_opt_set_default_flags(krb5_context context, krb5_get_init_creds_opt_set_renew_life(opt, t); krb5_appdefault_boolean(context, appname, realm, "no-addresses", - KRB5_ADDRESSLESS_DEFAULT, &b); + FALSE, &b); if (b) - krb5_get_init_creds_opt_set_address_list (opt, &no_addrs); + krb5_get_init_creds_opt_set_addressless (context, opt, TRUE); #if 0 krb5_appdefault_boolean(context, appname, realm, "anonymous", FALSE, &b); @@ -326,7 +358,52 @@ krb5_get_init_creds_opt_set_pac_request(krb5_context context, if (ret) return ret; opt->opt_private->req_pac = req_pac ? - KRB5_PA_PAC_REQ_TRUE : - KRB5_PA_PAC_REQ_FALSE; + KRB5_INIT_CREDS_TRISTATE_TRUE : + KRB5_INIT_CREDS_TRISTATE_FALSE; + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_get_error(krb5_context context, + krb5_get_init_creds_opt *opt, + KRB_ERROR **error) +{ + krb5_error_code ret; + + *error = NULL; + + ret = require_ext_opt(context, opt, "init_creds_opt_get_error"); + if (ret) + return ret; + + if (opt->opt_private->error == NULL) + return 0; + + *error = malloc(sizeof(**error)); + if (*error == NULL) { + krb5_set_error_string(context, "malloc - out memory"); + return ENOMEM; + } + + ret = copy_KRB_ERROR(*error, opt->opt_private->error); + if (ret) + krb5_clear_error_string(context); + + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_addressless(krb5_context context, + krb5_get_init_creds_opt *opt, + krb5_boolean addressless) +{ + krb5_error_code ret; + ret = require_ext_opt(context, opt, "init_creds_opt_set_pac_req"); + if (ret) + return ret; + if (addressless) + opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_TRUE; + else + opt->opt_private->addressless = KRB5_INIT_CREDS_TRISTATE_FALSE; return 0; } diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index c05386ec23..d43ae0ae6f 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -33,10 +33,10 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds_pw.c,v 1.94 2006/04/24 08:49:08 lha Exp $"); +RCSID("$Id: init_creds_pw.c,v 1.101 2006/10/02 12:00:59 lha Exp $"); typedef struct krb5_get_init_creds_ctx { - krb5_kdc_flags flags; + KDCOptions flags; krb5_creds cred; krb5_addresses *addrs; krb5_enctype *etypes; @@ -52,7 +52,7 @@ typedef struct krb5_get_init_creds_ctx { const char *password; krb5_s2k_proc key_proc; - krb5_get_init_creds_req_pac req_pac; + krb5_get_init_creds_tristate req_pac; krb5_pk_init_ctx pk_init_ctx; } krb5_get_init_creds_ctx; @@ -256,9 +256,10 @@ print_expire (krb5_context context, } } +static krb5_addresses no_addrs = { 0, NULL }; + static krb5_error_code get_init_creds_common(krb5_context context, - krb5_creds *creds, krb5_principal client, krb5_deltat start_time, const char *in_tkt_service, @@ -275,6 +276,8 @@ get_init_creds_common(krb5_context context, if (options == NULL) { krb5_get_init_creds_opt_init (&default_opt); options = &default_opt; + } else { + _krb5_get_init_creds_opt_free_krb5_error(options); } if (options->opt_private) { @@ -283,13 +286,12 @@ get_init_creds_common(krb5_context context, ctx->req_pac = options->opt_private->req_pac; ctx->pk_init_ctx = options->opt_private->pk_init_ctx; } else - ctx->req_pac = KRB5_PA_PAC_DONT_CARE; + ctx->req_pac = KRB5_INIT_CREDS_TRISTATE_UNSET; if (ctx->key_proc == NULL) ctx->key_proc = default_s2k_func; ctx->pre_auth_types = NULL; - ctx->flags.i = 0; ctx->addrs = NULL; ctx->etypes = NULL; ctx->pre_auth_types = NULL; @@ -300,20 +302,35 @@ get_init_creds_common(krb5_context context, if (ret) return ret; - ctx->flags.i = 0; - if (options->flags & KRB5_GET_INIT_CREDS_OPT_FORWARDABLE) - ctx->flags.b.forwardable = options->forwardable; + ctx->flags.forwardable = options->forwardable; if (options->flags & KRB5_GET_INIT_CREDS_OPT_PROXIABLE) - ctx->flags.b.proxiable = options->proxiable; + ctx->flags.proxiable = options->proxiable; if (start_time) - ctx->flags.b.postdated = 1; + ctx->flags.postdated = 1; if (ctx->cred.times.renew_till) - ctx->flags.b.renewable = 1; - if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) + ctx->flags.renewable = 1; + if (options->flags & KRB5_GET_INIT_CREDS_OPT_ADDRESS_LIST) { ctx->addrs = options->address_list; + } else if (options->opt_private) { + switch (options->opt_private->addressless) { + case KRB5_INIT_CREDS_TRISTATE_UNSET: +#if KRB5_ADDRESSLESS_DEFAULT == TRUE + ctx->addrs = &no_addrs; +#else + ctx->addrs = NULL; +#endif + break; + case KRB5_INIT_CREDS_TRISTATE_FALSE: + ctx->addrs = NULL; + break; + case KRB5_INIT_CREDS_TRISTATE_TRUE: + ctx->addrs = &no_addrs; + break; + } + } if (options->flags & KRB5_GET_INIT_CREDS_OPT_ETYPE_LIST) { etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); @@ -341,7 +358,7 @@ get_init_creds_common(krb5_context context, if (options->flags & KRB5_GET_INIT_CREDS_OPT_SALT) ; /* XXX */ if (options->flags & KRB5_GET_INIT_CREDS_OPT_ANONYMOUS) - ctx->flags.b.request_anonymous = options->anonymous; + ctx->flags.request_anonymous = options->anonymous; return 0; } @@ -478,7 +495,7 @@ krb5_get_init_creds_keytab(krb5_context context, krb5_error_code ret; krb5_keytab_key_proc_args *a; - ret = get_init_creds_common(context, creds, client, start_time, + ret = get_init_creds_common(context, client, start_time, in_tkt_service, options, &ctx); if (ret) goto out; @@ -493,7 +510,7 @@ krb5_get_init_creds_keytab(krb5_context context, a->keytab = keytab; ret = krb5_get_in_cred (context, - ctx.flags.i, + KDCOptions2int(ctx.flags), ctx.addrs, ctx.etypes, ctx.pre_auth_types, @@ -522,7 +539,7 @@ krb5_get_init_creds_keytab(krb5_context context, static krb5_error_code init_creds_init_as_req (krb5_context context, - krb5_kdc_flags opts, + KDCOptions opts, const krb5_creds *creds, const krb5_addresses *addrs, const krb5_enctype *etypes, @@ -534,7 +551,7 @@ init_creds_init_as_req (krb5_context context, a->pvno = 5; a->msg_type = krb_as_req; - a->req_body.kdc_options = opts.b; + a->req_body.kdc_options = opts; a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; @@ -1028,12 +1045,12 @@ pa_data_add_pac_request(krb5_context context, void *buf; switch (ctx->req_pac) { - case KRB5_PA_PAC_DONT_CARE: + case KRB5_INIT_CREDS_TRISTATE_UNSET: return 0; /* don't bother */ - case KRB5_PA_PAC_REQ_TRUE: + case KRB5_INIT_CREDS_TRISTATE_TRUE: req.include_pac = 1; break; - case KRB5_PA_PAC_REQ_FALSE: + case KRB5_INIT_CREDS_TRISTATE_FALSE: req.include_pac = 0; } @@ -1176,7 +1193,7 @@ process_pa_data_to_key(krb5_context context, static krb5_error_code init_cred_loop(krb5_context context, - const krb5_get_init_creds_opt *init_cred_opts, + krb5_get_init_creds_opt *init_cred_opts, const krb5_prompter_fct prompter, void *prompter_data, krb5_get_init_creds_ctx *ctx, @@ -1196,6 +1213,8 @@ init_cred_loop(krb5_context context, memset(&md, 0, sizeof(md)); memset(&rep, 0, sizeof(rep)); + _krb5_get_init_creds_opt_free_krb5_error(init_cred_opts); + if (ret_as_reply) memset(ret_as_reply, 0, sizeof(*ret_as_reply)); @@ -1211,7 +1230,7 @@ init_cred_loop(krb5_context context, ctx->pk_nonce = ctx->nonce; /* - * Increase counter when we want other pre-auth types than + * Increase counter when we want other pre-auth types then * KRB5_PA_ENC_TIMESTAMP. */ #define MAX_PA_COUNTER 3 @@ -1306,6 +1325,9 @@ init_cred_loop(krb5_context context, krb5_free_error_contents(context, &error); send_to_kdc_flags |= KRB5_KRBHST_FLAGS_LARGE_MSG; } else { + _krb5_get_init_creds_opt_set_krb5_error(context, + init_cred_opts, + &error); if (ret_as_reply) rep.error = error; else @@ -1332,7 +1354,7 @@ init_cred_loop(krb5_context context, NULL, ctx->nonce, FALSE, - ctx->flags.b.request_anonymous, + ctx->flags.request_anonymous, NULL, NULL); krb5_free_keyblock(context, key); @@ -1344,7 +1366,7 @@ out: if (ret == 0 && ret_as_reply) *ret_as_reply = rep; - else + else krb5_free_kdc_rep (context, &rep); return ret; } @@ -1367,7 +1389,7 @@ krb5_get_init_creds(krb5_context context, memset(&kdc_reply, 0, sizeof(kdc_reply)); - ret = get_init_creds_common(context, creds, client, start_time, + ret = get_init_creds_common(context, client, start_time, in_tkt_service, options, &ctx); if (ret) goto out; @@ -1391,7 +1413,7 @@ krb5_get_init_creds(krb5_context context, case KRB5KDC_ERR_KEY_EXPIRED : /* try to avoid recursion */ - /* don't try to change password where there where none */ + /* don't try to change password where then where none */ if (prompter == NULL || ctx.password == NULL) goto out; @@ -1528,13 +1550,13 @@ krb5_get_init_creds_keyblock(krb5_context context, struct krb5_get_init_creds_ctx ctx; krb5_error_code ret; - ret = get_init_creds_common(context, creds, client, start_time, + ret = get_init_creds_common(context, client, start_time, in_tkt_service, options, &ctx); if (ret) goto out; ret = krb5_get_in_cred (context, - ctx.flags.i, + KDCOptions2int(ctx.flags), ctx.addrs, ctx.etypes, ctx.pre_auth_types, diff --git a/source4/heimdal/lib/krb5/k524_err.c b/source4/heimdal/lib/krb5/k524_err.c new file mode 100644 index 0000000000..266d3ee577 --- /dev/null +++ b/source4/heimdal/lib/krb5/k524_err.c @@ -0,0 +1,30 @@ +/* Generated from k524_err.et */ +/* $Id: k524_err.et,v 1.1 2001/06/20 02:44:11 joda Exp $ */ + +#include <stddef.h> +#include <com_err.h> +#include "k524_err.h" + +static const char *k524_error_strings[] = { + /* 000 */ "wrong keytype in ticket", + /* 001 */ "incorrect network address", + /* 002 */ "cannot convert V5 principal", + /* 003 */ "V5 realm name longer than V4 maximum", + /* 004 */ "kerberos V4 error server", + /* 005 */ "encoding too large at server", + /* 006 */ "decoding out of data", + /* 007 */ "service not responding", + NULL +}; + +#define num_errors 8 + +void initialize_k524_error_table_r(struct et_list **list) +{ + initialize_error_table_r(list, k524_error_strings, num_errors, ERROR_TABLE_BASE_k524); +} + +void initialize_k524_error_table(void) +{ + init_error_table(k524_error_strings, ERROR_TABLE_BASE_k524, num_errors); +} diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index 9ba288e22b..968b6079b7 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -17,7 +17,7 @@ _krb5_aes_cts_encrypt ( const unsigned char */*in*/, unsigned char */*out*/, size_t /*len*/, - const void */*aes_key*/, + const AES_KEY */*key*/, unsigned char */*ivec*/, const int /*encryptp*/); @@ -46,6 +46,12 @@ _krb5_dh_group_ok ( struct krb5_dh_moduli **/*moduli*/, char **/*name*/); +krb5_error_code KRB5_LIB_FUNCTION +_krb5_enctype_to_oid ( + krb5_context /*context*/, + krb5_enctype /*etype*/, + heim_oid */*oid*/); + krb5_error_code _krb5_expand_default_cc_name ( krb5_context /*context*/, @@ -101,8 +107,17 @@ _krb5_get_init_creds_opt_copy ( krb5_get_init_creds_opt **/*out*/); void KRB5_LIB_FUNCTION +_krb5_get_init_creds_opt_free_krb5_error (krb5_get_init_creds_opt */*opt*/); + +void KRB5_LIB_FUNCTION _krb5_get_init_creds_opt_free_pkinit (krb5_get_init_creds_opt */*opt*/); +void KRB5_LIB_FUNCTION +_krb5_get_init_creds_opt_set_krb5_error ( + krb5_context /*context*/, + krb5_get_init_creds_opt */*opt*/, + const KRB_ERROR */*error*/); + krb5_ssize_t KRB5_LIB_FUNCTION _krb5_get_int ( void */*buffer*/, @@ -312,8 +327,8 @@ _krb5_pk_load_id ( struct krb5_pk_identity **/*ret_id*/, const char */*user_id*/, const char */*anchor_id*/, - char * const */*chain*/, - char * const */*revoke*/, + char * const */*chain_list*/, + char * const */*revoke_list*/, krb5_prompter_fct /*prompter*/, void */*prompter_data*/, char */*password*/); @@ -372,7 +387,7 @@ _krb5_principal2principalname ( krb5_error_code KRB5_LIB_FUNCTION _krb5_principalname2krb5_principal ( - krb5_context /* context */, + krb5_context /*context*/, krb5_principal */*principal*/, const PrincipalName /*from*/, const Realm /*realm*/); @@ -383,6 +398,12 @@ _krb5_put_int ( unsigned long /*value*/, size_t /*size*/); +krb5_error_code KRB5_LIB_FUNCTION +_krb5_s4u2self_to_checksumdata ( + krb5_context /*context*/, + const PA_S4U2Self */*self*/, + krb5_data */*data*/); + int _krb5_send_and_recv_tcp ( int /*fd*/, diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 37293ff982..2010e25f5a 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -1066,13 +1066,6 @@ krb5_crypto_get_checksum_type ( krb5_cksumtype */*type*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_crypto_get_params ( - krb5_context /*context*/, - const krb5_crypto /*crypto*/, - const krb5_data */*params*/, - krb5_data */*ivec*/); - -krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_getblocksize ( krb5_context /*context*/, krb5_crypto /*crypto*/, @@ -1104,13 +1097,6 @@ krb5_crypto_init ( krb5_crypto */*crypto*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_crypto_set_params ( - krb5_context /*context*/, - const krb5_crypto /*crypto*/, - const krb5_data */*ivec*/, - krb5_data */*params*/); - -krb5_error_code KRB5_LIB_FUNCTION krb5_data_alloc ( krb5_data */*p*/, int /*len*/); @@ -1246,6 +1232,169 @@ krb5_derive_key ( size_t /*constant_len*/, krb5_keyblock **/*derived_key*/); +krb5_error_code +krb5_digest_alloc ( + krb5_context /*context*/, + krb5_digest */*digest*/); + +void +krb5_digest_free (krb5_digest /*digest*/); + +krb5_error_code +krb5_digest_get_a1_hash ( + krb5_context /*context*/, + krb5_digest /*digest*/, + krb5_data */*data*/); + +krb5_error_code +krb5_digest_get_client_binding ( + krb5_context /*context*/, + krb5_digest /*digest*/, + char **/*type*/, + char **/*binding*/); + +const char * +krb5_digest_get_identifier ( + krb5_context /*context*/, + krb5_digest /*digest*/); + +const char * +krb5_digest_get_opaque ( + krb5_context /*context*/, + krb5_digest /*digest*/); + +const char * +krb5_digest_get_responseData ( + krb5_context /*context*/, + krb5_digest /*digest*/); + +const char * +krb5_digest_get_rsp ( + krb5_context /*context*/, + krb5_digest /*digest*/); + +const char * +krb5_digest_get_server_nonce ( + krb5_context /*context*/, + krb5_digest /*digest*/); + +krb5_error_code +krb5_digest_get_tickets ( + krb5_context /*context*/, + krb5_digest /*digest*/, + Ticket **/*tickets*/); + +krb5_error_code +krb5_digest_init_request ( + krb5_context /*context*/, + krb5_digest /*digest*/, + krb5_realm /*realm*/, + krb5_ccache /*ccache*/); + +krb5_error_code +krb5_digest_request ( + krb5_context /*context*/, + krb5_digest /*digest*/, + krb5_realm /*realm*/, + krb5_ccache /*ccache*/); + +krb5_error_code +krb5_digest_set_authentication_user ( + krb5_context /*context*/, + krb5_digest /*digest*/, + krb5_principal /*authentication_user*/); + +krb5_error_code +krb5_digest_set_authid ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*authid*/); + +krb5_error_code +krb5_digest_set_client_nonce ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*nonce*/); + +krb5_error_code +krb5_digest_set_digest ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*dgst*/); + +krb5_error_code +krb5_digest_set_hostname ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*hostname*/); + +krb5_error_code +krb5_digest_set_identifier ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*id*/); + +krb5_error_code +krb5_digest_set_method ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*method*/); + +krb5_error_code +krb5_digest_set_nonceCount ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*nonce_count*/); + +krb5_error_code +krb5_digest_set_opaque ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*opaque*/); + +krb5_error_code +krb5_digest_set_qop ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*qop*/); + +krb5_error_code +krb5_digest_set_realm ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*realm*/); + +krb5_error_code +krb5_digest_set_server_cb ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*type*/, + const char */*binding*/); + +krb5_error_code +krb5_digest_set_server_nonce ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*nonce*/); + +krb5_error_code +krb5_digest_set_type ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*type*/); + +krb5_error_code +krb5_digest_set_uri ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*uri*/); + +krb5_error_code +krb5_digest_set_username ( + krb5_context /*context*/, + krb5_digest /*digest*/, + const char */*username*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_domain_x500_decode ( krb5_context /*context*/, @@ -1377,12 +1526,6 @@ krb5_enctype_to_keytype ( krb5_keytype */*keytype*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_enctype_to_oid ( - krb5_context /*context*/, - krb5_enctype /*etype*/, - heim_oid */*oid*/); - -krb5_error_code KRB5_LIB_FUNCTION krb5_enctype_to_string ( krb5_context /*context*/, krb5_enctype /*etype*/, @@ -1652,6 +1795,54 @@ krb5_get_credentials_with_flags ( krb5_creds **/*out_creds*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + krb5_ccache /*ccache*/, + krb5_const_principal /*inprinc*/, + krb5_creds **/*out_creds*/); + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_add_options ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + krb5_flags /*options*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_alloc ( + krb5_context /*context*/, + krb5_get_creds_opt */*opt*/); + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_free ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/); + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_enctype ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + krb5_enctype /*enctype*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_impersonate ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + krb5_const_principal /*self*/); + +void KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_options ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + krb5_flags /*options*/); + +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_creds_opt_set_ticket ( + krb5_context /*context*/, + krb5_get_creds_opt /*opt*/, + const Ticket */*ticket*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_get_default_config_files (char ***/*pfilenames*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1674,6 +1865,9 @@ krb5_get_default_realms ( krb5_context /*context*/, krb5_realm **/*realms*/); +krb5_boolean KRB5_LIB_FUNCTION +krb5_get_dns_canonize_hostname (krb5_context /*context*/); + const char* KRB5_LIB_FUNCTION krb5_get_err_text ( krb5_context /*context*/, @@ -1710,7 +1904,7 @@ krb5_get_forwarded_creds ( krb5_error_code KRB5_LIB_FUNCTION krb5_get_host_realm ( krb5_context /*context*/, - const char */*host*/, + const char */*targethost*/, krb5_realm **/*realms*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1823,6 +2017,12 @@ krb5_get_init_creds_opt_alloc ( void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_free (krb5_get_init_creds_opt */*opt*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_get_error ( + krb5_context /*context*/, + krb5_get_init_creds_opt */*opt*/, + KRB_ERROR **/*error*/); + void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init (krb5_get_init_creds_opt */*opt*/); @@ -1831,6 +2031,12 @@ krb5_get_init_creds_opt_set_address_list ( krb5_get_init_creds_opt */*opt*/, krb5_addresses */*addresses*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_init_creds_opt_set_addressless ( + krb5_context /*context*/, + krb5_get_init_creds_opt */*opt*/, + krb5_boolean /*addressless*/); + void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_set_anonymous ( krb5_get_init_creds_opt */*opt*/, @@ -1874,8 +2080,8 @@ krb5_get_init_creds_opt_set_pkinit ( krb5_principal /*principal*/, const char */*user_id*/, const char */*x509_anchors*/, - char * const * /*chain*/, - char * const * /*revoke*/, + char * const * /*pool*/, + char * const * /*pki_revoke*/, int /*flags*/, krb5_prompter_fct /*prompter*/, void */*prompter_data*/, @@ -1930,6 +2136,12 @@ krb5_get_kdc_cred ( krb5_creds **out_creds ); krb5_error_code KRB5_LIB_FUNCTION +krb5_get_kdc_sec_offset ( + krb5_context /*context*/, + int32_t */*sec*/, + int32_t */*usec*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_get_krb524hst ( krb5_context /*context*/, const krb5_realm */*realm*/, @@ -2035,6 +2247,9 @@ krb5_initlog ( krb5_boolean KRB5_LIB_FUNCTION krb5_is_thread_safe (void); +const krb5_enctype * KRB5_LIB_FUNCTION +krb5_kerberos_enctypes (krb5_context /*context*/); + krb5_enctype krb5_keyblock_get_enctype (const krb5_keyblock */*block*/); @@ -2412,15 +2627,10 @@ krb5_parse_name ( krb5_principal */*principal*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_parse_name_mustrealm ( - krb5_context /*context*/, - const char */*name*/, - krb5_principal */*principal*/); - -krb5_error_code KRB5_LIB_FUNCTION -krb5_parse_name_norealm ( +krb5_parse_name_flags ( krb5_context /*context*/, const char */*name*/, + int /*flags*/, krb5_principal */*principal*/); const char* KRB5_LIB_FUNCTION @@ -2447,7 +2657,7 @@ krb5_prepend_config_files_default ( const char */*filelist*/, char ***/*pfilenames*/); -krb5_realm* KRB5_LIB_FUNCTION +krb5_realm * KRB5_LIB_FUNCTION krb5_princ_realm ( krb5_context /*context*/, krb5_principal /*principal*/); @@ -2793,6 +3003,11 @@ krb5_ret_string ( char **/*string*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_ret_stringnl ( + krb5_storage */*sp*/, + char **/*string*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_ret_stringz ( krb5_storage */*sp*/, char **/*string*/); @@ -2877,6 +3092,11 @@ krb5_set_default_realm ( krb5_context /*context*/, const char */*realm*/); +void KRB5_LIB_FUNCTION +krb5_set_dns_canonicalize_hostname ( + krb5_context /*context*/, + krb5_boolean /*flag*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_set_error_string ( krb5_context /*context*/, @@ -2926,10 +3146,9 @@ krb5_set_real_time ( int32_t /*usec*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_set_send_recv_func ( +krb5_set_send_to_kdc_func ( krb5_context /*context*/, - krb5_send_and_recv_func_t /*func*/, - krb5_send_and_recv_close_func_t /*close_fn*/, + krb5_send_to_kdc_func /*func*/, void */*data*/); void KRB5_LIB_FUNCTION @@ -3110,6 +3329,11 @@ krb5_store_string ( const char */*s*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_store_stringnl ( + krb5_storage */*sp*/, + const char */*s*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_store_stringz ( krb5_storage */*sp*/, const char */*s*/); @@ -3254,24 +3478,26 @@ krb5_unparse_name_fixed ( size_t /*len*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_fixed_short ( +krb5_unparse_name_fixed_flags ( krb5_context /*context*/, krb5_const_principal /*principal*/, + int /*flags*/, char */*name*/, size_t /*len*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_norealm ( +krb5_unparse_name_fixed_short ( krb5_context /*context*/, krb5_const_principal /*principal*/, - char **/*name*/); + char */*name*/, + size_t /*len*/); krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_norealm_fixed ( +krb5_unparse_name_flags ( krb5_context /*context*/, krb5_const_principal /*principal*/, - char */*name*/, - size_t /*len*/); + int /*flags*/, + char **/*name*/); krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_short ( diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 32fdd6d383..4b5058094b 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2006 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h,v 1.241 2006/05/05 09:29:36 lha Exp $ */ +/* $Id: krb5.h,v 1.253 2006/10/20 18:12:06 lha Exp $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -72,6 +72,12 @@ typedef const void *krb5_const_pointer; struct krb5_crypto_data; typedef struct krb5_crypto_data *krb5_crypto; +struct krb5_get_creds_opt_data; +typedef struct krb5_get_creds_opt_data *krb5_get_creds_opt; + +struct krb5_digest; +typedef struct krb5_digest *krb5_digest; + typedef CKSUMTYPE krb5_cksumtype; typedef Checksum krb5_checksum; @@ -203,8 +209,16 @@ typedef enum krb5_key_usage { /* Encryption of the SAM-TRACK-ID field */ KRB5_KU_PA_SERVER_REFERRAL = 26, /* Keyusage for the server referral in a TGS req */ - KRB5_KU_SAM_ENC_NONCE_SAD = 27 + KRB5_KU_SAM_ENC_NONCE_SAD = 27, /* Encryption of the SAM-NONCE-OR-SAD field */ + KRB5_KU_TGS_IMPERSONATE = -17, + /* Checksum type used in the impersonate field */ + KRB5_KU_DIGEST_ENCRYPT = -18, + /* Encryption key usage used in the digest encryption field */ + KRB5_KU_DIGEST_OPAQUE = -19, + /* Checksum key usage used in the digest opaque field */ + KRB5_KU_KRB5SIGNEDPATH = -21 + /* Checksum key usage on KRB5SignedPath */ } krb5_key_usage; typedef krb5_key_usage krb5_keyusage; @@ -256,9 +270,7 @@ typedef enum krb5_keytype { KEYTYPE_AES128 = 17, KEYTYPE_AES256 = 18, KEYTYPE_ARCFOUR = 23, - KEYTYPE_ARCFOUR_56 = 24, - KEYTYPE_RC2 = -0x1005, - KEYTYPE_AES192 = -0x1006 + KEYTYPE_ARCFOUR_56 = 24 } krb5_keytype; typedef EncryptionKey krb5_keyblock; @@ -339,6 +351,9 @@ typedef union { #define KRB5_GC_CACHED (1U << 0) #define KRB5_GC_USER_USER (1U << 1) #define KRB5_GC_EXPIRED_OK (1U << 2) +#define KRB5_GC_NO_STORE (1U << 3) +#define KRB5_GC_FORWARDABLE (1U << 4) +#define KRB5_GC_NO_TRANSIT_CHECK (1U << 5) /* constants for compare_creds (and cc_retrieve_cred) */ #define KRB5_TC_DONT_MATCH_REALM (1U << 31) @@ -413,49 +428,6 @@ typedef struct krb5_config_binding krb5_config_binding; typedef krb5_config_binding krb5_config_section; -typedef struct krb5_context_data { - krb5_enctype *etypes; - krb5_enctype *etypes_des; - char **default_realms; - time_t max_skew; - time_t kdc_timeout; - unsigned max_retries; - int32_t kdc_sec_offset; - int32_t kdc_usec_offset; - krb5_config_section *cf; - struct et_list *et_list; - struct krb5_log_facility *warn_dest; - krb5_cc_ops *cc_ops; - int num_cc_ops; - const char *http_proxy; - const char *time_fmt; - krb5_boolean log_utc; - const char *default_keytab; - const char *default_keytab_modify; - krb5_boolean use_admin_kdc; - krb5_addresses *extra_addresses; - krb5_boolean scan_interfaces; /* `ifconfig -a' */ - krb5_boolean srv_lookup; /* do SRV lookups */ - krb5_boolean srv_try_txt; /* try TXT records also */ - int32_t fcache_vno; /* create cache files w/ this - version */ - int num_kt_types; /* # of registered keytab types */ - struct krb5_keytab_data *kt_types; /* registered keytab types */ - const char *date_fmt; - char *error_string; - char error_buf[256]; - krb5_addresses *ignore_addresses; - char *default_cc_name; - int pkinit_flags; - void *mutex; /* protects error_string/error_buf */ - int large_msg_size; - krb5_boolean fdns; /* Lookup hostnames to find full name, or send as-is */ - struct send_and_recv *send_and_recv; /* Alternate functions for KDC communication */ - void *mem_ctx; /* Some parts of Samba4 need a valid - memory context (under the event - context) to use */ -} krb5_context_data; - enum { KRB5_PKINIT_WIN2K = 1, /* wire compatible with Windows 2k */ KRB5_PKINIT_PACKET_CABLE = 2 /* use packet cable standard */ @@ -578,8 +550,8 @@ typedef struct krb5_auth_context_data { krb5_rcache rcache; - krb5_keytype keytype; /* ¿requested key type ? */ - krb5_cksumtype cksumtype; /* ¡requested checksum type! */ + krb5_keytype keytype; /* ¿requested key type ? */ + krb5_cksumtype cksumtype; /* ¡requested checksum type! */ }krb5_auth_context_data, *krb5_auth_context; @@ -609,6 +581,8 @@ typedef EncAPRepPart krb5_ap_rep_enc_part; #define KRB5_TGS_NAME_SIZE (6) #define KRB5_TGS_NAME ("krbtgt") +#define KRB5_DIGEST_NAME ("digest") + /* variables */ extern const char *krb5_config_file; @@ -618,7 +592,8 @@ typedef enum { KRB5_PROMPT_TYPE_PASSWORD = 0x1, KRB5_PROMPT_TYPE_NEW_PASSWORD = 0x2, KRB5_PROMPT_TYPE_NEW_PASSWORD_AGAIN = 0x3, - KRB5_PROMPT_TYPE_PREAUTH = 0x4 + KRB5_PROMPT_TYPE_PREAUTH = 0x4, + KRB5_PROMPT_TYPE_INFO = 0x5 } krb5_prompt_type; typedef struct _krb5_prompt { @@ -754,12 +729,23 @@ enum { KRB5_KRBHST_FLAGS_LARGE_MSG = 2 }; -typedef int (*krb5_send_and_recv_func_t)(krb5_context, - void *, - krb5_krbhst_info *, - const krb5_data *, - krb5_data *); -typedef void (*krb5_send_and_recv_close_func_t)(krb5_context, void*); +typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, + void *, + krb5_krbhst_info *, + const krb5_data *, + krb5_data *); + +/* flags for krb5_parse_name_flags */ +enum { + KRB5_PRINCIPAL_PARSE_NO_REALM = 1, + KRB5_PRINCIPAL_PARSE_MUST_REALM = 2 +}; + +/* flags for krb5_unparse_name_flags */ +enum { + KRB5_PRINCIPAL_UNPARSE_SHORT = 1, + KRB5_PRINCIPAL_UNPARSE_NO_REALM = 2 +}; struct credentials; /* this is to keep the compiler happy */ struct getargs; diff --git a/source4/heimdal/lib/krb5/krb5_err.c b/source4/heimdal/lib/krb5/krb5_err.c new file mode 100644 index 0000000000..9185f729d5 --- /dev/null +++ b/source4/heimdal/lib/krb5/krb5_err.c @@ -0,0 +1,271 @@ +/* Generated from krb5_err.et */ +/* $Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $ */ + +#include <stddef.h> +#include <com_err.h> +#include "krb5_err.h" + +static const char *krb5_error_strings[] = { + /* 000 */ "No error", + /* 001 */ "Client's entry in database has expired", + /* 002 */ "Server's entry in database has expired", + /* 003 */ "Requested protocol version not supported", + /* 004 */ "Client's key is encrypted in an old master key", + /* 005 */ "Server's key is encrypted in an old master key", + /* 006 */ "Client not found in Kerberos database", + /* 007 */ "Server not found in Kerberos database", + /* 008 */ "Principal has multiple entries in Kerberos database", + /* 009 */ "Client or server has a null key", + /* 010 */ "Ticket is ineligible for postdating", + /* 011 */ "Requested effective lifetime is negative or too short", + /* 012 */ "KDC policy rejects request", + /* 013 */ "KDC can't fulfill requested option", + /* 014 */ "KDC has no support for encryption type", + /* 015 */ "KDC has no support for checksum type", + /* 016 */ "KDC has no support for padata type", + /* 017 */ "KDC has no support for transited type", + /* 018 */ "Clients credentials have been revoked", + /* 019 */ "Credentials for server have been revoked", + /* 020 */ "TGT has been revoked", + /* 021 */ "Client not yet valid - try again later", + /* 022 */ "Server not yet valid - try again later", + /* 023 */ "Password has expired", + /* 024 */ "Preauthentication failed", + /* 025 */ "Additional pre-authentication required", + /* 026 */ "Requested server and ticket don't match", + /* 027 */ "Reserved krb5 error (27)", + /* 028 */ "Reserved krb5 error (28)", + /* 029 */ "Reserved krb5 error (29)", + /* 030 */ "Reserved krb5 error (30)", + /* 031 */ "Decrypt integrity check failed", + /* 032 */ "Ticket expired", + /* 033 */ "Ticket not yet valid", + /* 034 */ "Request is a replay", + /* 035 */ "The ticket isn't for us", + /* 036 */ "Ticket/authenticator don't match", + /* 037 */ "Clock skew too great", + /* 038 */ "Incorrect net address", + /* 039 */ "Protocol version mismatch", + /* 040 */ "Invalid message type", + /* 041 */ "Message stream modified", + /* 042 */ "Message out of order", + /* 043 */ "Invalid cross-realm ticket", + /* 044 */ "Key version is not available", + /* 045 */ "Service key not available", + /* 046 */ "Mutual authentication failed", + /* 047 */ "Incorrect message direction", + /* 048 */ "Alternative authentication method required", + /* 049 */ "Incorrect sequence number in message", + /* 050 */ "Inappropriate type of checksum in message", + /* 051 */ "Policy rejects transited path", + /* 052 */ "Response too big for UDP, retry with TCP", + /* 053 */ "Reserved krb5 error (53)", + /* 054 */ "Reserved krb5 error (54)", + /* 055 */ "Reserved krb5 error (55)", + /* 056 */ "Reserved krb5 error (56)", + /* 057 */ "Reserved krb5 error (57)", + /* 058 */ "Reserved krb5 error (58)", + /* 059 */ "Reserved krb5 error (59)", + /* 060 */ "Generic error (see e-text)", + /* 061 */ "Field is too long for this implementation", + /* 062 */ "Client not trusted", + /* 063 */ "KDC not trusted", + /* 064 */ "Invalid signature", + /* 065 */ "DH parameters not accepted", + /* 066 */ "Reserved krb5 error (66)", + /* 067 */ "Reserved krb5 error (67)", + /* 068 */ "Reserved krb5 error (68)", + /* 069 */ "User to user required", + /* 070 */ "Cannot verify certificate", + /* 071 */ "Certificate invalid", + /* 072 */ "Certificate revoked", + /* 073 */ "Revocation status unknown", + /* 074 */ "Revocation status unknown", + /* 075 */ "Inconsistent key purpose", + /* 076 */ "Digest in certificate not accepted", + /* 077 */ "paChecksum must be included", + /* 078 */ "Digest in signedData not accepted", + /* 079 */ "Public key encryption not supported", + /* 080 */ "Reserved krb5 error (80)", + /* 081 */ "Reserved krb5 error (81)", + /* 082 */ "Reserved krb5 error (82)", + /* 083 */ "Reserved krb5 error (83)", + /* 084 */ "Reserved krb5 error (84)", + /* 085 */ "Reserved krb5 error (85)", + /* 086 */ "Reserved krb5 error (86)", + /* 087 */ "Reserved krb5 error (87)", + /* 088 */ "Reserved krb5 error (88)", + /* 089 */ "Reserved krb5 error (89)", + /* 090 */ "Reserved krb5 error (90)", + /* 091 */ "Reserved krb5 error (91)", + /* 092 */ "Reserved krb5 error (92)", + /* 093 */ "Reserved krb5 error (93)", + /* 094 */ "Reserved krb5 error (94)", + /* 095 */ "Reserved krb5 error (95)", + /* 096 */ "Reserved krb5 error (96)", + /* 097 */ "Reserved krb5 error (97)", + /* 098 */ "Reserved krb5 error (98)", + /* 099 */ "Reserved krb5 error (99)", + /* 100 */ "Reserved krb5 error (100)", + /* 101 */ "Reserved krb5 error (101)", + /* 102 */ "Reserved krb5 error (102)", + /* 103 */ "Reserved krb5 error (103)", + /* 104 */ "Reserved krb5 error (104)", + /* 105 */ "Reserved krb5 error (105)", + /* 106 */ "Reserved krb5 error (106)", + /* 107 */ "Reserved krb5 error (107)", + /* 108 */ "Reserved krb5 error (108)", + /* 109 */ "Reserved krb5 error (109)", + /* 110 */ "Reserved krb5 error (110)", + /* 111 */ "Reserved krb5 error (111)", + /* 112 */ "Reserved krb5 error (112)", + /* 113 */ "Reserved krb5 error (113)", + /* 114 */ "Reserved krb5 error (114)", + /* 115 */ "Reserved krb5 error (115)", + /* 116 */ "Reserved krb5 error (116)", + /* 117 */ "Reserved krb5 error (117)", + /* 118 */ "Reserved krb5 error (118)", + /* 119 */ "Reserved krb5 error (119)", + /* 120 */ "Reserved krb5 error (120)", + /* 121 */ "Reserved krb5 error (121)", + /* 122 */ "Reserved krb5 error (122)", + /* 123 */ "Reserved krb5 error (123)", + /* 124 */ "Reserved krb5 error (124)", + /* 125 */ "Reserved krb5 error (125)", + /* 126 */ "Reserved krb5 error (126)", + /* 127 */ "Reserved krb5 error (127)", + /* 128 */ "$Id: krb5_err.et,v 1.14 2006/02/13 11:28:22 lha Exp $", + /* 129 */ "Invalid flag for file lock mode", + /* 130 */ "Cannot read password", + /* 131 */ "Password mismatch", + /* 132 */ "Password read interrupted", + /* 133 */ "Invalid character in component name", + /* 134 */ "Malformed representation of principal", + /* 135 */ "Can't open/find configuration file", + /* 136 */ "Improper format of configuration file", + /* 137 */ "Insufficient space to return complete information", + /* 138 */ "Invalid message type specified for encoding", + /* 139 */ "Credential cache name malformed", + /* 140 */ "Unknown credential cache type", + /* 141 */ "Matching credential not found", + /* 142 */ "End of credential cache reached", + /* 143 */ "Request did not supply a ticket", + /* 144 */ "Wrong principal in request", + /* 145 */ "Ticket has invalid flag set", + /* 146 */ "Requested principal and ticket don't match", + /* 147 */ "KDC reply did not match expectations", + /* 148 */ "Clock skew too great in KDC reply", + /* 149 */ "Client/server realm mismatch in initial ticket request", + /* 150 */ "Program lacks support for encryption type", + /* 151 */ "Program lacks support for key type", + /* 152 */ "Requested encryption type not used in message", + /* 153 */ "Program lacks support for checksum type", + /* 154 */ "Cannot find KDC for requested realm", + /* 155 */ "Kerberos service unknown", + /* 156 */ "Cannot contact any KDC for requested realm", + /* 157 */ "No local name found for principal name", + /* 158 */ "Mutual authentication failed", + /* 159 */ "Replay cache type is already registered", + /* 160 */ "No more memory to allocate (in replay cache code)", + /* 161 */ "Replay cache type is unknown", + /* 162 */ "Generic unknown RC error", + /* 163 */ "Message is a replay", + /* 164 */ "Replay I/O operation failed XXX", + /* 165 */ "Replay cache type does not support non-volatile storage", + /* 166 */ "Replay cache name parse/format error", + /* 167 */ "End-of-file on replay cache I/O", + /* 168 */ "No more memory to allocate (in replay cache I/O code)", + /* 169 */ "Permission denied in replay cache code", + /* 170 */ "I/O error in replay cache i/o code", + /* 171 */ "Generic unknown RC/IO error", + /* 172 */ "Insufficient system space to store replay information", + /* 173 */ "Can't open/find realm translation file", + /* 174 */ "Improper format of realm translation file", + /* 175 */ "Can't open/find lname translation database", + /* 176 */ "No translation available for requested principal", + /* 177 */ "Improper format of translation database entry", + /* 178 */ "Cryptosystem internal error", + /* 179 */ "Key table name malformed", + /* 180 */ "Unknown Key table type", + /* 181 */ "Key table entry not found", + /* 182 */ "End of key table reached", + /* 183 */ "Cannot write to specified key table", + /* 184 */ "Error writing to key table", + /* 185 */ "Cannot find ticket for requested realm", + /* 186 */ "DES key has bad parity", + /* 187 */ "DES key is a weak key", + /* 188 */ "Bad encryption type", + /* 189 */ "Key size is incompatible with encryption type", + /* 190 */ "Message size is incompatible with encryption type", + /* 191 */ "Credentials cache type is already registered.", + /* 192 */ "Key table type is already registered.", + /* 193 */ "Credentials cache I/O operation failed XXX", + /* 194 */ "Credentials cache file permissions incorrect", + /* 195 */ "No credentials cache file found", + /* 196 */ "Internal file credentials cache error", + /* 197 */ "Error writing to credentials cache file", + /* 198 */ "No more memory to allocate (in credentials cache code)", + /* 199 */ "Bad format in credentials cache", + /* 200 */ "No credentials found with supported encryption types", + /* 201 */ "Invalid KDC option combination (library internal error)", + /* 202 */ "Request missing second ticket", + /* 203 */ "No credentials supplied to library routine", + /* 204 */ "Bad sendauth version was sent", + /* 205 */ "Bad application version was sent (via sendauth)", + /* 206 */ "Bad response (during sendauth exchange)", + /* 207 */ "Server rejected authentication (during sendauth exchange)", + /* 208 */ "Unsupported preauthentication type", + /* 209 */ "Required preauthentication key not supplied", + /* 210 */ "Generic preauthentication failure", + /* 211 */ "Unsupported replay cache format version number", + /* 212 */ "Unsupported credentials cache format version number", + /* 213 */ "Unsupported key table format version number", + /* 214 */ "Program lacks support for address type", + /* 215 */ "Message replay detection requires rcache parameter", + /* 216 */ "Hostname cannot be canonicalized", + /* 217 */ "Cannot determine realm for host", + /* 218 */ "Conversion to service principal undefined for name type", + /* 219 */ "Initial Ticket response appears to be Version 4", + /* 220 */ "Cannot resolve KDC for requested realm", + /* 221 */ "Requesting ticket can't get forwardable tickets", + /* 222 */ "Bad principal name while trying to forward credentials", + /* 223 */ "Looping detected inside krb5_get_in_tkt", + /* 224 */ "Configuration file does not specify default realm", + /* 225 */ "Bad SAM flags in obtain_sam_padata", + /* 226 */ "Invalid encryption type in SAM challenge", + /* 227 */ "Missing checksum in SAM challenge", + /* 228 */ "Bad checksum in SAM challenge", + /* 229 */ "Reserved krb5 error (229)", + /* 230 */ "Reserved krb5 error (230)", + /* 231 */ "Reserved krb5 error (231)", + /* 232 */ "Reserved krb5 error (232)", + /* 233 */ "Reserved krb5 error (233)", + /* 234 */ "Reserved krb5 error (234)", + /* 235 */ "Reserved krb5 error (235)", + /* 236 */ "Reserved krb5 error (236)", + /* 237 */ "Reserved krb5 error (237)", + /* 238 */ "Program called an obsolete, deleted function", + /* 239 */ "Reserved krb5 error (239)", + /* 240 */ "Reserved krb5 error (240)", + /* 241 */ "Reserved krb5 error (241)", + /* 242 */ "Reserved krb5 error (242)", + /* 243 */ "Reserved krb5 error (243)", + /* 244 */ "Reserved krb5 error (244)", + /* 245 */ "Invalid key generation parameters from KDC", + /* 246 */ "Service not available", + /* 247 */ "Credential cache function not supported", + /* 248 */ "Invalid format of Kerberos lifetime or clock skew string", + NULL +}; + +#define num_errors 249 + +void initialize_krb5_error_table_r(struct et_list **list) +{ + initialize_error_table_r(list, krb5_error_strings, num_errors, ERROR_TABLE_BASE_krb5); +} + +void initialize_krb5_error_table(void) +{ + init_error_table(krb5_error_strings, ERROR_TABLE_BASE_krb5, num_errors); +} diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 4dcac40c7a..89b3c6ad40 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2002 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_locl.h,v 1.87 2006/02/09 11:36:27 lha Exp $ */ +/* $Id: krb5_locl.h,v 1.93 2006/10/20 18:13:31 lha Exp $ */ #ifndef __KRB5_LOCL_H__ #define __KRB5_LOCL_H__ @@ -136,6 +136,8 @@ struct sockaddr_dl; #include <krb5_asn1.h> +struct send_to_kdc; + /* XXX glue for pkinit */ struct krb5_pk_identity; struct krb5_pk_cert; @@ -151,6 +153,9 @@ struct _krb5_krb_auth_data; #include <krb5.h> #include <krb5_err.h> #include <asn1_err.h> +#ifdef PKINIT +#include <hx509_err.h> +#endif #include <krb5-private.h> #include "heim_threads.h" @@ -171,10 +176,10 @@ struct _krb5_krb_auth_data; #define KRB5_BUFSIZ 1024 typedef enum { - KRB5_PA_PAC_DONT_CARE = 0, - KRB5_PA_PAC_REQ_TRUE, - KRB5_PA_PAC_REQ_FALSE -} krb5_get_init_creds_req_pac; + KRB5_INIT_CREDS_TRISTATE_UNSET = 0, + KRB5_INIT_CREDS_TRISTATE_TRUE, + KRB5_INIT_CREDS_TRISTATE_FALSE +} krb5_get_init_creds_tristate; struct _krb5_get_init_creds_opt_private { int refcount; @@ -182,12 +187,57 @@ struct _krb5_get_init_creds_opt_private { const char *password; krb5_s2k_proc key_proc; /* PA_PAC_REQUEST */ - krb5_get_init_creds_req_pac req_pac; + krb5_get_init_creds_tristate req_pac; /* PKINIT */ krb5_pk_init_ctx pk_init_ctx; int canonicalize; + KRB_ERROR *error; + krb5_get_init_creds_tristate addressless; }; +typedef struct krb5_context_data { + krb5_enctype *etypes; + krb5_enctype *etypes_des; + char **default_realms; + time_t max_skew; + time_t kdc_timeout; + unsigned max_retries; + int32_t kdc_sec_offset; + int32_t kdc_usec_offset; + krb5_config_section *cf; + struct et_list *et_list; + struct krb5_log_facility *warn_dest; + krb5_cc_ops *cc_ops; + int num_cc_ops; + const char *http_proxy; + const char *time_fmt; + krb5_boolean log_utc; + const char *default_keytab; + const char *default_keytab_modify; + krb5_boolean use_admin_kdc; + krb5_addresses *extra_addresses; + krb5_boolean scan_interfaces; /* `ifconfig -a' */ + krb5_boolean srv_lookup; /* do SRV lookups */ + krb5_boolean srv_try_txt; /* try TXT records also */ + int32_t fcache_vno; /* create cache files w/ this + version */ + int num_kt_types; /* # of registered keytab types */ + struct krb5_keytab_data *kt_types; /* registered keytab types */ + const char *date_fmt; + char *error_string; + char error_buf[256]; + krb5_addresses *ignore_addresses; + char *default_cc_name; + int pkinit_flags; + void *mutex; /* protects error_string/error_buf */ + int large_msg_size; + int dns_canonicalize_hostname; + struct send_to_kdc *send_to_kdc; + void *mem_ctx; /* Some parts of Samba4 need a valid + memory context (under the event + context) to use */ +} krb5_context_data; + /* * Configurable options */ @@ -201,7 +251,7 @@ struct _krb5_get_init_creds_opt_private { #endif #ifndef KRB5_ADDRESSLESS_DEFAULT -#define KRB5_ADDRESSLESS_DEFAULT FALSE +#define KRB5_ADDRESSLESS_DEFAULT TRUE #endif #endif /* __KRB5_LOCL_H__ */ diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index 221bd706f4..e7b2579229 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <resolve.h> -RCSID("$Id: krbhst.c,v 1.55 2006/04/02 10:32:20 lha Exp $"); +RCSID("$Id: krbhst.c,v 1.57 2006/10/06 17:11:02 lha Exp $"); static int string_to_proto(const char *string) @@ -422,6 +422,15 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, struct addrinfo hints; char portstr[NI_MAXSERV]; + /* + * Don't try forever in case the DNS server keep returning us + * entries (like wildcard entries or the .nu TLD) + */ + if(kd->fallback_count >= 5) { + kd->flags |= KD_FALLBACK; + return 0; + } + if(kd->fallback_count == 0) asprintf(&host, "%s.%s.", serv_string, kd->realm); else @@ -659,9 +668,8 @@ common_init(krb5_context context, } /* For 'realms' without a . do not even think of going to DNS */ - if (!strchr(realm, '.')) { + if (!strchr(realm, '.')) kd->flags |= KD_CONFIG_EXISTS; - } if (flags & KRB5_KRBHST_FLAGS_LARGE_MSG) kd->flags |= KD_LARGE_MSG; diff --git a/source4/heimdal/lib/krb5/misc.c b/source4/heimdal/lib/krb5/misc.c index baf63f6d52..f04f8d9996 100644 --- a/source4/heimdal/lib/krb5/misc.c +++ b/source4/heimdal/lib/krb5/misc.c @@ -33,4 +33,53 @@ #include "krb5_locl.h" -RCSID("$Id: misc.c,v 1.5 1999/12/02 17:05:11 joda Exp $"); +RCSID("$Id: misc.c,v 1.6 2006/06/06 14:57:47 lha Exp $"); + +krb5_error_code KRB5_LIB_FUNCTION +_krb5_s4u2self_to_checksumdata(krb5_context context, + const PA_S4U2Self *self, + krb5_data *data) +{ + krb5_error_code ret; + krb5_ssize_t ssize; + krb5_storage *sp; + size_t size; + int i; + + sp = krb5_storage_emem(); + if (sp == NULL) { + krb5_clear_error_string(context); + return ENOMEM; + } + ret = krb5_store_int32(sp, self->name.name_type); + if (ret) + goto out; + for (i = 0; i < self->name.name_string.len; i++) { + size = strlen(self->name.name_string.val[i]); + ssize = krb5_storage_write(sp, self->name.name_string.val[i], size); + if (ssize != size) { + ret = ENOMEM; + goto out; + } + } + size = strlen(self->realm); + ssize = krb5_storage_write(sp, self->realm, size); + if (ssize != size) { + ret = ENOMEM; + goto out; + } + size = strlen(self->auth); + ssize = krb5_storage_write(sp, self->auth, size); + if (ssize != size) { + ret = ENOMEM; + goto out; + } + + ret = krb5_storage_to_data(sp, data); + krb5_storage_free(sp); + return ret; + +out: + krb5_clear_error_string(context); + return ret; +} diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c index b7f06c1582..b9075b3079 100755 --- a/source4/heimdal/lib/krb5/mit_glue.c +++ b/source4/heimdal/lib/krb5/mit_glue.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: mit_glue.c,v 1.7 2005/05/18 04:21:44 lha Exp $"); +RCSID("$Id: mit_glue.c,v 1.8 2006/10/14 09:51:02 lha Exp $"); /* * Glue for MIT API @@ -98,7 +98,7 @@ krb5_c_get_checksum(krb5_context context, const krb5_checksum *cksum, if (*data == NULL) return ENOMEM; - ret = copy_octet_string(&cksum->checksum, *data); + ret = der_copy_octet_string(&cksum->checksum, *data); if (ret) { free(*data); *data = NULL; @@ -113,7 +113,7 @@ krb5_c_set_checksum(krb5_context context, krb5_checksum *cksum, krb5_cksumtype type, const krb5_data *data) { cksum->cksumtype = type; - return copy_octet_string(data, &cksum->checksum); + return der_copy_octet_string(data, &cksum->checksum); } void KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 00f7b4ebd9..f519b5ad08 100755 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: pkinit.c,v 1.99 2006/05/07 12:32:38 lha Exp $"); +RCSID("$Id: pkinit.c,v 1.110 2006/10/14 09:52:50 lha Exp $"); struct krb5_dh_moduli { char *name; @@ -69,7 +69,7 @@ struct krb5_pk_identity { hx509_certs certs; hx509_certs anchors; hx509_certs certpool; - hx509_revoke_ctx revoke; + hx509_revoke_ctx revokectx; }; struct krb5_pk_cert { @@ -344,8 +344,8 @@ build_auth_pack(krb5_context context, ALLOC(a->clientPublicValue, 1); if (a->clientPublicValue == NULL) return ENOMEM; - ret = copy_oid(oid_id_dhpublicnumber(), - &a->clientPublicValue->algorithm.algorithm); + ret = der_copy_oid(oid_id_dhpublicnumber(), + &a->clientPublicValue->algorithm.algorithm); if (ret) return ret; @@ -392,7 +392,7 @@ build_auth_pack(krb5_context context, ASN1_MALLOC_ENCODE(DHPublicKey, dhbuf.data, dhbuf.length, &dh_pub_key, &size, ret); - free_heim_integer(&dh_pub_key); + der_free_heim_integer(&dh_pub_key); if (ret) return ret; if (size != dhbuf.length) @@ -413,7 +413,7 @@ _krb5_pk_mk_ContentInfo(krb5_context context, { krb5_error_code ret; - ret = copy_oid(oid, &content_info->contentType); + ret = der_copy_oid(oid, &content_info->contentType); if (ret) return ret; ALLOC(content_info->content, 1); @@ -672,8 +672,16 @@ _krb5_pk_verify_sign(krb5_context context, contentType, content, &signer_certs); - if (ret) + if (ret) { + char *s = hx509_get_error_string(id->hx509ctx, ret); + if (s) { + krb5_set_error_string(context, + "CMS verify signed failed with %s", s); + free(s); + } else + krb5_clear_error_string(context); return ret; + } *signer = calloc(1, sizeof(**signer)); if (*signer == NULL) { @@ -833,7 +841,9 @@ pk_verify_host(krb5_context context, oid_id_pkinit_san(), &list); if (ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Failed to find the PK-INIT " + "subjectAltName in the KDC certificate"); + return ret; } @@ -845,7 +855,9 @@ pk_verify_host(krb5_context context, &r, NULL); if (ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Failed to decode the PK-INIT " + "subjectAltName in the KDC certificate"); + break; } @@ -856,7 +868,7 @@ pk_verify_host(krb5_context context, { krb5_set_error_string(context, "KDC have wrong realm name in " "the certificate"); - ret = EINVAL; + ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; } free_KRB5PrincipalName(&r); @@ -875,7 +887,8 @@ pk_verify_host(krb5_context context, hi->ai->ai_addr, hi->ai->ai_addrlen); if (ret) - krb5_set_error_string(context, "Address mismatch in the KDC certificate"); + krb5_set_error_string(context, "Address mismatch in " + "the KDC certificate"); } return ret; } @@ -901,7 +914,7 @@ pk_rd_pa_reply_enckey(krb5_context context, krb5_data content; heim_oid contentType = { 0, NULL }; - if (heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), &rep->contentType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } @@ -913,8 +926,10 @@ pk_rd_pa_reply_enckey(krb5_context context, ret = hx509_cms_unenvelope(ctx->id->hx509ctx, ctx->id->certs, + HX509_CMS_UE_DONT_REQUIRE_KU_ENCIPHERMENT, rep->content->data, rep->content->length, + NULL, &contentType, &content); if (ret) @@ -935,7 +950,7 @@ pk_rd_pa_reply_enckey(krb5_context context, goto out; } - if (heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) { + if (der_heim_oid_cmp(&ci.contentType, oid_id_pkcs7_signedData())) { ret = EINVAL; /* XXX */ krb5_set_error_string(context, "PKINIT: Invalid content type"); goto out; @@ -964,19 +979,18 @@ pk_rd_pa_reply_enckey(krb5_context context, /* make sure that it is the kdc's certificate */ ret = pk_verify_host(context, realm, hi, ctx, host); if (ret) { - krb5_set_error_string(context, "PKINIT: failed verify host: %d", ret); goto out; } #if 0 if (type == COMPAT_WIN2K) { - if (heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { + if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; } } else { - if (heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { + if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; @@ -1002,7 +1016,7 @@ pk_rd_pa_reply_enckey(krb5_context context, out: if (host) _krb5_pk_cert_free(host); - free_oid(&contentType); + der_free_oid(&contentType); krb5_data_free(&content); return ret; @@ -1034,7 +1048,7 @@ pk_rd_pa_reply_dh(krb5_context context, krb5_data_zero(&content); memset(&kdc_dh_info, 0, sizeof(kdc_dh_info)); - if (heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) { + if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), &rep->contentType)) { krb5_set_error_string(context, "PKINIT: Invalid content type"); return EINVAL; } @@ -1059,7 +1073,7 @@ pk_rd_pa_reply_dh(krb5_context context, if (ret) goto out; - if (heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { + if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { krb5_set_error_string(context, "pkinit - dh reply contains wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; goto out; @@ -1324,20 +1338,28 @@ hx_pass_prompter(void *data, const hx509_prompt *prompter) password_data.data = prompter->reply.data; password_data.length = prompter->reply.length; - prompt.prompt = "Enter your private key passphrase: "; - prompt.hidden = 1; + + prompt.prompt = prompter->prompt; + prompt.hidden = hx509_prompt_hidden(prompter->type); prompt.reply = &password_data; - if (prompter->hidden) + + switch (prompter->type) { + case HX509_PROMPT_TYPE_INFO: + prompt.type = KRB5_PROMPT_TYPE_INFO; + break; + case HX509_PROMPT_TYPE_PASSWORD: + case HX509_PROMPT_TYPE_QUESTION: + default: prompt.type = KRB5_PROMPT_TYPE_PASSWORD; - else - prompt.type = KRB5_PROMPT_TYPE_PREAUTH; /* XXX */ + break; + } ret = (*p->prompter)(p->context, p->prompter_data, NULL, NULL, 1, &prompt); if (ret) { memset (prompter->reply.data, 0, prompter->reply.length); - return 0; + return 1; } - return strlen(prompter->reply.data); + return 0; } @@ -1354,8 +1376,8 @@ _krb5_pk_load_id(krb5_context context, struct krb5_pk_identity **ret_id, const char *user_id, const char *anchor_id, - char * const *chain, - char * const *revoke, + char * const *chain_list, + char * const *revoke_list, krb5_prompter_fct prompter, void *prompter_data, char *password) @@ -1392,7 +1414,7 @@ _krb5_pk_load_id(krb5_context context, goto out; ret = hx509_lock_init(id->hx509ctx, &lock); - if (password) + if (password && password[0]) hx509_lock_add_password(lock, password); if (prompter) { @@ -1405,7 +1427,7 @@ _krb5_pk_load_id(krb5_context context, goto out; } - ret = hx509_certs_init(id->hx509ctx, user_id, 0, NULL, &id->certs); + ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs); if (ret) goto out; @@ -1418,33 +1440,36 @@ _krb5_pk_load_id(krb5_context context, if (ret) goto out; - while (chain && *chain) { - ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain); + while (chain_list && *chain_list) { + ret = hx509_certs_append(id->hx509ctx, id->certpool, + NULL, *chain_list); if (ret) { krb5_set_error_string(context, "pkinit failed to load chain %s", - *chain); + *chain_list); goto out; } - chain++; + chain_list++; } - if (revoke) { - ret = hx509_revoke_init(id->hx509ctx, &id->revoke); + if (revoke_list) { + ret = hx509_revoke_init(id->hx509ctx, &id->revokectx); if (ret) { krb5_set_error_string(context, "revoke failed to init"); goto out; } - while (*revoke) { - ret = hx509_revoke_add_crl(id->hx509ctx, id->revoke, *revoke); + while (*revoke_list) { + ret = hx509_revoke_add_crl(id->hx509ctx, + id->revokectx, + *revoke_list); if (ret) { krb5_set_error_string(context, "pkinit failed to load revoke %s", - *revoke); + *revoke_list); goto out; } - revoke++; + revoke_list++; } } else hx509_context_set_missing_revoke(id->hx509ctx, 1); @@ -1454,7 +1479,7 @@ _krb5_pk_load_id(krb5_context context, goto out; hx509_verify_attach_anchors(id->verify_ctx, id->anchors); - hx509_verify_attach_revoke(id->verify_ctx, id->revoke); + hx509_verify_attach_revoke(id->verify_ctx, id->revokectx); out: if (ret) { @@ -1462,7 +1487,7 @@ out: hx509_certs_free(&id->certs); hx509_certs_free(&id->anchors); hx509_certs_free(&id->certpool); - hx509_revoke_free(&id->revoke); + hx509_revoke_free(&id->revokectx); hx509_context_free(&id->hx509ctx); free(id); } else @@ -1588,9 +1613,9 @@ _krb5_parse_moduli_line(krb5_context context, return 0; out: free(m1->name); - free_heim_integer(&m1->p); - free_heim_integer(&m1->g); - free_heim_integer(&m1->q); + der_free_heim_integer(&m1->p); + der_free_heim_integer(&m1->g); + der_free_heim_integer(&m1->q); free(m1); return ret; } @@ -1601,9 +1626,9 @@ _krb5_free_moduli(struct krb5_dh_moduli **moduli) int i; for (i = 0; moduli[i] != NULL; i++) { free(moduli[i]->name); - free_heim_integer(&moduli[i]->p); - free_heim_integer(&moduli[i]->g); - free_heim_integer(&moduli[i]->q); + der_free_heim_integer(&moduli[i]->p); + der_free_heim_integer(&moduli[i]->g); + der_free_heim_integer(&moduli[i]->q); free(moduli[i]); } free(moduli); @@ -1712,9 +1737,9 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits, *name = NULL; for (i = 0; moduli[i] != NULL; i++) { - if (heim_integer_cmp(&moduli[i]->g, g) == 0 && - heim_integer_cmp(&moduli[i]->p, p) == 0 && - (q == NULL || heim_integer_cmp(&moduli[i]->q, q) == 0)) + if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 && + der_heim_integer_cmp(&moduli[i]->p, p) == 0 && + (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0)) { if (bits && bits > moduli[i]->bits) { krb5_set_error_string(context, "PKINIT: DH group parameter %s " @@ -1769,8 +1794,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, krb5_principal principal, const char *user_id, const char *x509_anchors, - char * const * chain, - char * const * revoke, + char * const * pool, + char * const * pki_revoke, int flags, krb5_prompter_fct prompter, void *prompter_data, @@ -1778,6 +1803,7 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, { #ifdef PKINIT krb5_error_code ret; + char *anchors = NULL; if (opt->opt_private == NULL) { krb5_set_error_string(context, "PKINIT: on non extendable opt"); @@ -1797,12 +1823,33 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, opt->opt_private->pk_init_ctx->require_eku = 1; opt->opt_private->pk_init_ctx->require_krbtgt_otherName = 1; + + /* XXX implement krb5_appdefault_strings */ + if (pool == NULL) + pool = krb5_config_get_strings(context, NULL, + "appdefaults", + "pkinit-pool", + NULL); + + if (pki_revoke == NULL) + pki_revoke = krb5_config_get_strings(context, NULL, + "appdefaults", + "pkinit-revoke", + NULL); + + if (x509_anchors == NULL) { + krb5_appdefault_string(context, "kinit", + krb5_principal_get_realm(context, principal), + "pkinit-anchors", NULL, &anchors); + x509_anchors = anchors; + } + ret = _krb5_pk_load_id(context, &opt->opt_private->pk_init_ctx->id, user_id, x509_anchors, - chain, - revoke, + pool, + pki_revoke, prompter, prompter_data, password); diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index f6e3847cce..4d13e7db11 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -41,7 +41,7 @@ #include <fnmatch.h> #include "resolve.h" -RCSID("$Id: principal.c,v 1.95 2006/04/24 15:16:14 lha Exp $"); +RCSID("$Id: principal.c,v 1.99 2006/10/18 06:53:22 lha Exp $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -91,17 +91,11 @@ krb5_principal_get_comp_string(krb5_context context, return princ_ncomp(principal, component); } -enum realm_presence { - MAY, - MUSTNOT, - MUST -}; - -static krb5_error_code -parse_name(krb5_context context, - const char *name, - enum realm_presence realm_presence, - krb5_principal *principal) +krb5_error_code KRB5_LIB_FUNCTION +krb5_parse_name_flags(krb5_context context, + const char *name, + int flags, + krb5_principal *principal) { krb5_error_code ret; heim_general_string *comp; @@ -117,6 +111,17 @@ parse_name(krb5_context context, char c; int got_realm = 0; + *principal = NULL; + +#define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM) + + if ((flags & RFLAGS) == RFLAGS) { + krb5_set_error_string(context, "Can't require both realm and " + "no realm at the same time"); + return KRB5_ERR_NO_SERVICE; + } +#undef RFLAGS + /* count number of component */ ncomp = 1; for(p = name; *p; p++){ @@ -191,32 +196,33 @@ parse_name(krb5_context context, } *q++ = c; } - if (got_realm) { - if (realm_presence == MUSTNOT) { - krb5_set_error_string (context, "realm found in 'short' principal expected to be without one!"); + if(got_realm){ + if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { + krb5_set_error_string (context, "realm found in 'short' principal " + "expected to be without one"); ret = KRB5_PARSE_MALFORMED; goto exit; - } else { - realm = malloc(q - start + 1); - if (realm == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); - ret = ENOMEM; - goto exit; - } - memcpy(realm, start, q - start); - realm[q - start] = 0; } + realm = malloc(q - start + 1); + if (realm == NULL) { + krb5_set_error_string (context, "malloc: out of memory"); + ret = ENOMEM; + goto exit; + } + memcpy(realm, start, q - start); + realm[q - start] = 0; }else{ - if (realm_presence == MAY) { - ret = krb5_get_default_realm (context, &realm); - if (ret) - goto exit; - } else if (realm_presence == MUSTNOT) { - realm = NULL; - } else if (realm_presence == MUST) { - krb5_set_error_string (context, "realm NOT found in principal expected to be with one!"); + if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) { + krb5_set_error_string (context, "realm NOT found in principal " + "expected to be with one"); ret = KRB5_PARSE_MALFORMED; goto exit; + } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { + realm = NULL; + } else { + ret = krb5_get_default_realm (context, &realm); + if (ret) + goto exit; } comp[n] = malloc(q - start + 1); @@ -256,24 +262,9 @@ krb5_parse_name(krb5_context context, const char *name, krb5_principal *principal) { - return parse_name(context, name, MAY, principal); + return krb5_parse_name_flags(context, name, 0, principal); } -krb5_error_code KRB5_LIB_FUNCTION -krb5_parse_name_norealm(krb5_context context, - const char *name, - krb5_principal *principal) -{ - return parse_name(context, name, MUSTNOT, principal); -} - -krb5_error_code KRB5_LIB_FUNCTION -krb5_parse_name_mustrealm(krb5_context context, - const char *name, - krb5_principal *principal) -{ - return parse_name(context, name, MUST, principal); -} static const char quotable_chars[] = " \n\t\b\\/@"; static const char replace_chars[] = " ntb\\/@"; @@ -301,23 +292,47 @@ unparse_name_fixed(krb5_context context, krb5_const_principal principal, char *name, size_t len, - krb5_boolean short_form) + int flags) { size_t idx = 0; int i; + int short_form = (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) != 0; + int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) != 0; + + if (!no_realm && princ_realm(principal) == NULL) { + krb5_set_error_string(context, "Realm missing from principal, " + "can't unparse"); + return ERANGE; + } + for(i = 0; i < princ_num_comp(principal); i++){ if(i) add_char(name, idx, len, '/'); idx = quote_string(princ_ncomp(principal, i), name, idx, len); - if(idx == len) + if(idx == len) { + krb5_set_error_string(context, "Out of space printing principal"); return ERANGE; + } } /* add realm if different from default realm */ - if(!short_form) { + if(short_form && !no_realm) { + krb5_realm r; + krb5_error_code ret; + ret = krb5_get_default_realm(context, &r); + if(ret) + return ret; + if(strcmp(princ_realm(principal), r) != 0) + short_form = 0; + free(r); + } + if(!short_form && !no_realm) { add_char(name, idx, len, '@'); idx = quote_string(princ_realm(principal), name, idx, len); - if(idx == len) + if(idx == len) { + krb5_set_error_string(context, + "Out of space printing realm of principal"); return ERANGE; + } } return 0; } @@ -328,57 +343,48 @@ krb5_unparse_name_fixed(krb5_context context, char *name, size_t len) { - return unparse_name_fixed(context, principal, name, len, FALSE); + return unparse_name_fixed(context, principal, name, len, 0); } krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_norealm_fixed(krb5_context context, - krb5_const_principal principal, - char *name, - size_t len) +krb5_unparse_name_fixed_short(krb5_context context, + krb5_const_principal principal, + char *name, + size_t len) { - return unparse_name_fixed(context, principal, name, len, TRUE); + return unparse_name_fixed(context, principal, name, len, + KRB5_PRINCIPAL_UNPARSE_SHORT); } krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_fixed_short(krb5_context context, +krb5_unparse_name_fixed_flags(krb5_context context, krb5_const_principal principal, + int flags, char *name, size_t len) { - krb5_realm r; - krb5_error_code ret; - krb5_boolean short_form = TRUE; - ret = krb5_get_default_realm(context, &r); - if(ret) - return ret; - if(strcmp(princ_realm(principal), r) != 0) - short_form = 0; - free(r); - return unparse_name_fixed(context, principal, name, len, short_form); + return unparse_name_fixed(context, principal, name, len, flags); } static krb5_error_code unparse_name(krb5_context context, krb5_const_principal principal, char **name, - krb5_boolean short_flag) + int flags) { size_t len = 0, plen; int i; krb5_error_code ret; /* count length */ - if (!short_flag) { + if (princ_realm(principal)) { plen = strlen(princ_realm(principal)); + if(strcspn(princ_realm(principal), quotable_chars) == plen) len += plen; else len += 2*plen; - len++; - } else { - len = 0; + len++; /* '@' */ } - for(i = 0; i < princ_num_comp(principal); i++){ plen = strlen(princ_ncomp(principal, i)); if(strcspn(princ_ncomp(principal, i), quotable_chars) == plen) @@ -387,13 +393,13 @@ unparse_name(krb5_context context, len += 2*plen; len++; } - len++; + len++; /* '\0' */ *name = malloc(len); if(*name == NULL) { krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } - ret = unparse_name_fixed(context, principal, *name, len, short_flag); + ret = unparse_name_fixed(context, principal, *name, len, flags); if(ret) { free(*name); *name = NULL; @@ -406,32 +412,24 @@ krb5_unparse_name(krb5_context context, krb5_const_principal principal, char **name) { - return unparse_name(context, principal, name, FALSE); + return unparse_name(context, principal, name, 0); } krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_short(krb5_context context, +krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, + int flags, char **name) { - krb5_realm r; - krb5_error_code ret; - krb5_boolean short_form = TRUE; - ret = krb5_get_default_realm(context, &r); - if(ret) - return ret; - if(strcmp(princ_realm(principal), r) != 0) - short_form = 0; - free(r); - return unparse_name(context, principal, name, short_form); + return unparse_name(context, principal, name, flags); } krb5_error_code KRB5_LIB_FUNCTION -krb5_unparse_name_norealm(krb5_context context, - krb5_const_principal principal, - char **name) +krb5_unparse_name_short(krb5_context context, + krb5_const_principal principal, + char **name) { - return unparse_name(context, principal, name, TRUE); + return unparse_name(context, principal, name, KRB5_PRINCIPAL_UNPARSE_SHORT); } #if 0 /* not implemented */ @@ -447,7 +445,7 @@ krb5_unparse_name_ext(krb5_context context, #endif -krb5_realm* KRB5_LIB_FUNCTION +krb5_realm * KRB5_LIB_FUNCTION krb5_princ_realm(krb5_context context, krb5_principal principal) { @@ -455,7 +453,6 @@ krb5_princ_realm(krb5_context context, } - void KRB5_LIB_FUNCTION krb5_princ_set_realm(krb5_context context, krb5_principal principal, diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c index 01b5188bae..46a36c9aac 100644 --- a/source4/heimdal/lib/krb5/rd_cred.c +++ b/source4/heimdal/lib/krb5/rd_cred.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_cred.c,v 1.28 2006/04/02 02:27:33 lha Exp $"); +RCSID("$Id: rd_cred.c,v 1.29 2006/10/06 17:04:47 lha Exp $"); static krb5_error_code compare_addrs(krb5_context context, @@ -265,7 +265,8 @@ krb5_rd_cred(krb5_context context, krb5_abortx(context, "internal error in ASN.1 encoder"); copy_EncryptionKey (&kci->key, &creds->session); if (kci->prealm && kci->pname) - _krb5_principalname2krb5_principal (context, &creds->client, + _krb5_principalname2krb5_principal (context, + &creds->client, *kci->pname, *kci->prealm); if (kci->flags) diff --git a/source4/heimdal/lib/krb5/rd_rep.c b/source4/heimdal/lib/krb5/rd_rep.c index 53138d9f45..6b7f27c3cf 100644 --- a/source4/heimdal/lib/krb5/rd_rep.c +++ b/source4/heimdal/lib/krb5/rd_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_rep.c,v 1.25 2005/06/17 07:49:33 lha Exp $"); +RCSID("$Id: rd_rep.c,v 1.26 2006/08/21 09:19:22 lha Exp $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_rep(krb5_context context, @@ -92,7 +92,10 @@ krb5_rd_rep(krb5_context context, if (auth_context->flags & KRB5_AUTH_CONTEXT_DO_TIME) { if ((*repl)->ctime != auth_context->authenticator->ctime || - (*repl)->cusec != auth_context->authenticator->cusec) { + (*repl)->cusec != auth_context->authenticator->cusec) + { + krb5_free_ap_rep_enc_part(context, *repl); + *repl = NULL; ret = KRB5KRB_AP_ERR_MUT_FAIL; krb5_clear_error_string (context); goto out; @@ -114,6 +117,8 @@ void KRB5_LIB_FUNCTION krb5_free_ap_rep_enc_part (krb5_context context, krb5_ap_rep_enc_part *val) { - free_EncAPRepPart (val); - free (val); + if (val) { + free_EncAPRepPart (val); + free (val); + } } diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index c0bb710a59..c424a73a34 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001, 2003 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2001, 2003 - 2005 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_req.c,v 1.63 2006/04/10 10:14:44 lha Exp $"); +RCSID("$Id: rd_req.c,v 1.66 2006/10/06 17:04:29 lha Exp $"); static krb5_error_code decrypt_tkt_enc_part (krb5_context context, @@ -376,12 +376,14 @@ krb5_verify_ap_req2(krb5_context context, if(ret) goto out; - ret = _krb5_principalname2krb5_principal(context, - &t->server, ap_req->ticket.sname, + ret = _krb5_principalname2krb5_principal(context, + &t->server, + ap_req->ticket.sname, ap_req->ticket.realm); if (ret) goto out; - ret = _krb5_principalname2krb5_principal(context, - &t->client, t->ticket.cname, + ret = _krb5_principalname2krb5_principal(context, + &t->client, + t->ticket.cname, t->ticket.crealm); if (ret) goto out; @@ -402,10 +404,12 @@ krb5_verify_ap_req2(krb5_context context, krb5_principal p1, p2; krb5_boolean res; - _krb5_principalname2krb5_principal(context, &p1, + _krb5_principalname2krb5_principal(context, + &p1, ac->authenticator->cname, ac->authenticator->crealm); - _krb5_principalname2krb5_principal(context, &p2, + _krb5_principalname2krb5_principal(context, + &p2, t->ticket.cname, t->ticket.crealm); res = krb5_principal_compare (context, p1, p2); @@ -607,7 +611,8 @@ krb5_rd_req_return_keyblock(krb5_context context, return ret; if(server == NULL){ - _krb5_principalname2krb5_principal(context, &service, + _krb5_principalname2krb5_principal(context, + &service, ap_req.ticket.sname, ap_req.ticket.realm); server = service; diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index 0bcafa70a1..11c07c9e8f 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -33,32 +33,13 @@ #include "krb5_locl.h" -RCSID("$Id: send_to_kdc.c,v 1.58 2006/04/02 02:32:03 lha Exp $"); +RCSID("$Id: send_to_kdc.c,v 1.60 2006/10/20 18:42:01 lha Exp $"); -struct send_and_recv { - krb5_send_and_recv_func_t func; - krb5_send_and_recv_close_func_t close; - void *data; +struct send_to_kdc { + krb5_send_to_kdc_func func; + void *data; }; -krb5_error_code KRB5_LIB_FUNCTION -krb5_set_send_recv_func(krb5_context context, - krb5_send_and_recv_func_t func, - krb5_send_and_recv_close_func_t close_fn, - void *data) -{ - free(context->send_and_recv); - context->send_and_recv = malloc(sizeof(*context->send_and_recv)); - if (!context->send_and_recv) { - return ENOMEM; - } - context->send_and_recv->func = func; - context->send_and_recv->close = close_fn; - context->send_and_recv->data = data; - return 0; -} - - /* * send the data in `req' on the socket `fd' (which is datagram iff udp) * waiting `tmout' for a reply and returning the reply in `rep'. @@ -346,7 +327,7 @@ krb5_sendto (krb5_context context, krb5_krbhst_handle handle, krb5_data *receive) { - krb5_error_code ret = 0; + krb5_error_code ret; int fd; int i; @@ -356,27 +337,22 @@ krb5_sendto (krb5_context context, while (krb5_krbhst_next(context, handle, &hi) == 0) { struct addrinfo *ai, *a; - if (context->send_and_recv) { - ret = context->send_and_recv->func(context, - context->send_and_recv->data, - hi, send_data, receive); - if (ret) { - continue; - } else if (receive->length != 0) { - return 0; - } else { - continue; - } + if (context->send_to_kdc) { + struct send_to_kdc *s = context->send_to_kdc; + + ret = (*s->func)(context, s->data, + hi, send_data, receive); + if (ret == 0 && receive->length != 0) + goto out; + continue; } if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) { - if (send_via_proxy (context, hi, send_data, receive)) { - /* Try again, with next host */ - continue; - } else { - /* Success */ - return 0; + if (send_via_proxy (context, hi, send_data, receive) == 0) { + ret = 0; + goto out; } + continue; } ret = krb5_krbhst_get_addrinfo(context, hi, &ai); @@ -406,15 +382,16 @@ krb5_sendto (krb5_context context, break; } close (fd); - if(ret == 0 && receive->length != 0) { - return 0; - } + if(ret == 0 && receive->length != 0) + goto out; } } krb5_krbhst_reset(context, handle); } krb5_clear_error_string (context); - return KRB5_KDC_UNREACH; + ret = KRB5_KDC_UNREACH; +out: + return ret; } krb5_error_code KRB5_LIB_FUNCTION @@ -456,3 +433,27 @@ krb5_sendto_kdc_flags(krb5_context context, "unable to reach any KDC in realm %s", *realm); return ret; } + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_send_to_kdc_func(krb5_context context, + krb5_send_to_kdc_func func, + void *data) +{ + free(context->send_to_kdc); + if (func == NULL) { + context->send_to_kdc = NULL; + return 0; + } + + context->send_to_kdc = malloc(sizeof(*context->send_to_kdc)); + if (context->send_to_kdc == NULL) { + krb5_set_error_string(context, "Out of memory"); + return ENOMEM; + } + + context->send_to_kdc->func = func; + context->send_to_kdc->data = data; + return 0; +} + + diff --git a/source4/heimdal/lib/krb5/set_default_realm.c b/source4/heimdal/lib/krb5/set_default_realm.c index fd57b6fe67..965883309c 100644 --- a/source4/heimdal/lib/krb5/set_default_realm.c +++ b/source4/heimdal/lib/krb5/set_default_realm.c @@ -77,19 +77,8 @@ krb5_set_default_realm(krb5_context context, "libdefaults", "default_realm", NULL); - if (realms == NULL) { - char hostname[MAXHOSTNAMELEN]; - if (gethostname (hostname, sizeof(hostname))) { - return errno; - } - - if (strchr(hostname, '.') == NULL) { - /* There is no way we can get this mapping, as we can't do DNS */ - return KRB5_CONFIG_NODEFREALM; - } - ret = krb5_get_host_realm(context, hostname, - &realms); - } + if (realms == NULL) + ret = krb5_get_host_realm(context, NULL, &realms); } else { ret = string_to_list (context, realm, &realms); } diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c index a6f4a011a1..e75f28ca5f 100644 --- a/source4/heimdal/lib/krb5/store.c +++ b/source4/heimdal/lib/krb5/store.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store.c,v 1.58 2006/05/05 07:15:18 lha Exp $"); +RCSID("$Id: store.c,v 1.59 2006/08/18 08:39:13 lha Exp $"); #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) @@ -440,6 +440,76 @@ krb5_ret_stringz(krb5_storage *sp, return 0; } +krb5_error_code KRB5_LIB_FUNCTION +krb5_store_stringnl(krb5_storage *sp, const char *s) +{ + size_t len = strlen(s); + ssize_t ret; + + ret = sp->store(sp, s, len); + if(ret != len) { + if(ret < 0) + return ret; + else + return sp->eof_code; + } + ret = sp->store(sp, "\n", 1); + if(ret != 1) { + if(ret < 0) + return ret; + else + return sp->eof_code; + } + + return 0; + +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_ret_stringnl(krb5_storage *sp, + char **string) +{ + int expect_nl = 0; + char c; + char *s = NULL; + size_t len = 0; + ssize_t ret; + + while((ret = sp->fetch(sp, &c, 1)) == 1){ + char *tmp; + + if (c == '\r') { + expect_nl = 1; + continue; + } + if (expect_nl && c != '\n') { + free(s); + return KRB5_BADMSGTYPE; + } + + len++; + tmp = realloc (s, len); + if (tmp == NULL) { + free (s); + return ENOMEM; + } + s = tmp; + if(c == '\n') { + s[len - 1] = '\0'; + break; + } + s[len - 1] = c; + } + if(ret != 1){ + free(s); + if(ret == 0) + return sp->eof_code; + return ret; + } + *string = s; + return 0; +} + krb5_error_code KRB5_LIB_FUNCTION krb5_store_principal(krb5_storage *sp, diff --git a/source4/heimdal/lib/krb5/store_fd.c b/source4/heimdal/lib/krb5/store_fd.c index 46043a6761..835d3478e2 100644 --- a/source4/heimdal/lib/krb5/store_fd.c +++ b/source4/heimdal/lib/krb5/store_fd.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store_fd.c,v 1.12 2004/05/25 21:43:57 lha Exp $"); +RCSID("$Id: store_fd.c,v 1.13 2006/06/30 21:23:19 lha Exp $"); typedef struct fd_storage { int fd; @@ -74,13 +74,16 @@ krb5_storage_from_fd(int fd) fd = dup(fd); if (fd < 0) return NULL; - sp = malloc(sizeof(krb5_storage)); - if (sp == NULL) + sp = malloc(sizeof(krb5_storage)); + if (sp == NULL) { + close(fd); return NULL; + } sp->data = malloc(sizeof(fd_storage)); if (sp->data == NULL) { + close(fd); free(sp); return NULL; } diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 99cb778722..fdc2a1b3a5 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: ticket.c,v 1.14 2005/10/27 13:21:42 lha Exp $"); +RCSID("$Id: ticket.c,v 1.15 2006/10/14 09:53:19 lha Exp $"); krb5_error_code KRB5_LIB_FUNCTION krb5_free_ticket(krb5_context context, @@ -107,12 +107,16 @@ find_type_in_ad(krb5_context context, const AuthorizationData *ad, int level) { - krb5_error_code ret = ENOENT; + /* It is not an error if nothing in here, that is reported by *found */ + /* Setting a default error causes found to be set to FALSE, on + * recursion to an second embedded authz data even if the first + * element contains the required type */ + krb5_error_code ret = 0; int i; if (level > 9) { krb5_set_error_string(context, "Authorization data nested deeper " - "than %d levels, stop searching", level); + "then %d levels, stop searching", level); ret = ENOENT; /* XXX */ goto out; } @@ -124,7 +128,7 @@ find_type_in_ad(krb5_context context, */ for (i = 0; i < ad->len; i++) { if (!*found && ad->val[i].ad_type == type) { - ret = copy_octet_string(&ad->val[i].ad_data, data); + ret = der_copy_octet_string(&ad->val[i].ad_data, data); if (ret) { krb5_set_error_string(context, "malloc - out of memory"); goto out; |