From 9e6b0c28712ee77ce878809c8576826a3ba08d95 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Mar 2008 10:17:42 +1100 Subject: Merge lorikeet-heimdal -r 787 into Samba4 tree. Andrew Bartlett (This used to be commit d88b530522d3cef67c24422bd5182fb875d87ee2) --- source4/heimdal/lib/krb5/acache.c | 270 +++++++++++++--------- source4/heimdal/lib/krb5/add_et_list.c | 12 +- source4/heimdal/lib/krb5/addr_families.c | 282 +++++++++++++++++++++- source4/heimdal/lib/krb5/asn1_glue.c | 6 +- source4/heimdal/lib/krb5/auth_context.c | 8 +- source4/heimdal/lib/krb5/cache.c | 330 ++++++++++++++++++++------ source4/heimdal/lib/krb5/context.c | 334 ++++++++++++++++++++++++++- source4/heimdal/lib/krb5/convert_creds.c | 31 ++- source4/heimdal/lib/krb5/copy_host_realm.c | 13 +- source4/heimdal/lib/krb5/creds.c | 84 +++++-- source4/heimdal/lib/krb5/crypto.c | 63 +++-- source4/heimdal/lib/krb5/data.c | 100 +++++++- source4/heimdal/lib/krb5/eai_to_heim_errno.c | 26 ++- source4/heimdal/lib/krb5/error_string.c | 33 ++- source4/heimdal/lib/krb5/expand_hostname.c | 6 +- source4/heimdal/lib/krb5/fcache.c | 131 +++++++++-- source4/heimdal/lib/krb5/get_cred.c | 10 +- source4/heimdal/lib/krb5/get_for_creds.c | 94 +++++--- source4/heimdal/lib/krb5/get_in_tkt.c | 2 +- source4/heimdal/lib/krb5/init_creds.c | 2 +- source4/heimdal/lib/krb5/init_creds_pw.c | 12 +- source4/heimdal/lib/krb5/kcm.c | 30 ++- source4/heimdal/lib/krb5/keytab.c | 7 +- source4/heimdal/lib/krb5/keytab_file.c | 6 +- source4/heimdal/lib/krb5/keytab_keyfile.c | 6 +- source4/heimdal/lib/krb5/keytab_krb4.c | 28 ++- source4/heimdal/lib/krb5/krb5-private.h | 11 +- source4/heimdal/lib/krb5/krb5-protos.h | 50 +++- source4/heimdal/lib/krb5/krb5.h | 21 +- source4/heimdal/lib/krb5/krb5_ccapi.h | 8 +- source4/heimdal/lib/krb5/krb5_locl.h | 14 +- source4/heimdal/lib/krb5/mcache.c | 57 ++++- source4/heimdal/lib/krb5/n-fold.c | 23 +- source4/heimdal/lib/krb5/pac.c | 92 ++++---- source4/heimdal/lib/krb5/pkinit.c | 90 +++++--- source4/heimdal/lib/krb5/plugin.c | 23 +- source4/heimdal/lib/krb5/principal.c | 37 ++- source4/heimdal/lib/krb5/rd_priv.c | 2 +- source4/heimdal/lib/krb5/rd_req.c | 44 ++-- source4/heimdal/lib/krb5/send_to_kdc.c | 4 +- source4/heimdal/lib/krb5/store.c | 10 +- source4/heimdal/lib/krb5/store_emem.c | 21 +- source4/heimdal/lib/krb5/transited.c | 19 +- source4/heimdal/lib/krb5/v4_glue.c | 4 +- 44 files changed, 1969 insertions(+), 487 deletions(-) (limited to 'source4/heimdal/lib/krb5') diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 999ce7f120..775239cf6d 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2004 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 2004 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -37,7 +37,7 @@ #include #endif -RCSID("$Id: acache.c 19764 2007-01-08 15:31:01Z lha $"); +RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -188,11 +188,10 @@ make_cred_from_ccred(krb5_context context, ; if (i) { - cred->authdata.val = malloc(sizeof(cred->authdata.val[0]) * i); + cred->authdata.val = calloc(i, sizeof(cred->authdata.val[0])); if (cred->authdata.val == NULL) goto nomem; cred->authdata.len = i; - memset(cred->authdata.val, 0, sizeof(cred->authdata.val[0]) * i); for (i = 0; i < cred->authdata.len; i++) { cred->authdata.val[i].ad_type = incred->authdata[i]->type; ret = krb5_data_copy(&cred->authdata.val[i].ad_data, @@ -207,11 +206,10 @@ make_cred_from_ccred(krb5_context context, ; if (i) { - cred->addresses.val = malloc(sizeof(cred->addresses.val[0]) * i); + cred->addresses.val = calloc(i, sizeof(cred->addresses.val[0])); if (cred->addresses.val == NULL) goto nomem; cred->addresses.len = i; - memset(cred->addresses.val, 0, sizeof(cred->addresses.val[0]) * i); for (i = 0; i < cred->addresses.len; i++) { cred->addresses.val[i].addr_type = incred->addresses[i]->type; @@ -260,7 +258,7 @@ nomem: krb5_set_error_string(context, "malloc - out of memory"); fail: - krb5_free_creds_contents(context, cred); + krb5_free_cred_contents(context, cred); return ret; } @@ -331,6 +329,10 @@ make_ccred_from_cred(krb5_context context, for (i = 0; i < incred->addresses.len; i++) { cc_data *addr; addr = malloc(sizeof(*addr)); + if (addr == NULL) { + ret = ENOMEM; + goto fail; + } addr->type = incred->addresses.val[i].addr_type; addr->length = incred->addresses.val[i].address.length; addr->data = malloc(addr->length); @@ -383,20 +385,21 @@ fail: return ret; } -static char * -get_cc_name(cc_ccache_t cache) +static cc_int32 +get_cc_name(krb5_acc *a) { cc_string_t name; cc_int32 error; - char *str; - error = (*cache->func->get_name)(cache, &name); + error = (*a->ccache->func->get_name)(a->ccache, &name); if (error) - return NULL; + return error; - str = strdup(name->data); + a->cache_name = strdup(name->data); (*name->func->release)(name); - return str; + if (a->cache_name == NULL) + return ccErrNoMem; + return ccNoError; } @@ -405,17 +408,36 @@ acc_get_name(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); - static char n[255]; - char *name; + int32_t error; - name = get_cc_name(a->ccache); - if (name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - return NULL; - } - strlcpy(n, name, sizeof(n)); - free(name); - return n; + if (a->cache_name == NULL) { + krb5_error_code ret; + krb5_principal principal; + char *name; + + ret = _krb5_get_default_principal_local(context, &principal); + if (ret) + return NULL; + + ret = krb5_unparse_name(context, principal, &name); + krb5_free_principal(context, principal); + if (ret) + return NULL; + + error = (*a->context->func->create_new_ccache)(a->context, + cc_credentials_v5, + name, + &a->ccache); + krb5_xfree(name); + if (error) + return NULL; + + error = get_cc_name(a); + if (error) + return NULL; + } + + return a->cache_name; } static krb5_error_code @@ -448,23 +470,6 @@ acc_alloc(krb5_context context, krb5_ccache *id) return 0; } -static krb5_error_code -get_default_principal(krb5_context context, char **p) -{ - krb5_error_code ret; - krb5_principal principal; - - *p = NULL; - - ret = _krb5_get_default_principal_local(context, &principal); - if (ret) - return ret; - - ret = krb5_unparse_name(context, principal, p); - krb5_free_principal(context, principal); - return ret; -} - static krb5_error_code acc_resolve(krb5_context context, krb5_ccache *id, const char *res) { @@ -478,38 +483,22 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res) a = ACACHE(*id); - if (res == NULL || res[0] == '\0') { - error = (*a->context->func->open_default_ccache)(a->context, - &a->ccache); - if (error == ccErrCCacheNotFound) { - char *p; - - ret = get_default_principal(context, &p); - if (ret == 0) { - error = (*a->context->func->create_default_ccache)(a->context, - cc_credentials_v5, - p, - &a->ccache); - free(p); - } + error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); + if (error == ccNoError) { + error = get_cc_name(a); + if (error != ccNoError) { + acc_close(context, *id); + *id = NULL; + return translate_cc_error(context, error); } - if (error == 0) - a->cache_name = get_cc_name(a->ccache); + } else if (error == ccErrCCacheNotFound) { + a->ccache = NULL; + a->cache_name = NULL; + error = 0; } else { - error = (*a->context->func->open_ccache)(a->context, res, &a->ccache); - if (error == 0) - a->cache_name = strdup(res); - } - if (error != 0) { *id = NULL; return translate_cc_error(context, error); } - if (a->cache_name == NULL) { - acc_close(context, *id); - *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } return 0; } @@ -518,35 +507,17 @@ static krb5_error_code acc_gen_new(krb5_context context, krb5_ccache *id) { krb5_error_code ret; - cc_int32 error; krb5_acc *a; - char *p; - - ret = get_default_principal(context, &p); ret = acc_alloc(context, id); - if (ret) { - free(p); + if (ret) return ret; - } a = ACACHE(*id); - error = (*a->context->func->create_new_ccache)(a->context, - cc_credentials_v5, - p, &a->ccache); - free(p); - if (error) { - *id = NULL; - return translate_cc_error(context, error); - } - a->cache_name = get_cc_name(a->ccache); - if (a->cache_name == NULL) { - acc_close(context, *id); - *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; - } + a->ccache = NULL; + a->cache_name = NULL; + return 0; } @@ -555,9 +526,7 @@ acc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) { - cc_credentials_iterator_t iter; krb5_acc *a = ACACHE(id); - cc_credentials_t ccred; krb5_error_code ret; int32_t error; char *name; @@ -566,12 +535,17 @@ acc_initialize(krb5_context context, if (ret) return ret; - if (a->ccache == NULL) { + if (a->cache_name == NULL) { error = (*a->context->func->create_new_ccache)(a->context, cc_credentials_v5, name, &a->ccache); - } else { + free(name); + if (error == ccNoError) + error = get_cc_name(a); + } else { + cc_credentials_iterator_t iter; + cc_credentials_t ccred; error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { @@ -593,8 +567,6 @@ acc_initialize(krb5_context context, name); } - free(name); - return translate_cc_error(context, error); } @@ -629,6 +601,10 @@ acc_destroy(krb5_context context, error = (*a->ccache->func->destroy)(a->ccache); a->ccache = NULL; } + if (a->context) { + error = (a->context->func->release)(a->context); + a->context = NULL; + } return translate_cc_error(context, error); } @@ -643,6 +619,11 @@ acc_store_cred(krb5_context context, krb5_error_code ret; cc_int32 error; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + cred.version = cc_credentials_v5; cred.credentials.credentials_v5 = &v5cred; @@ -671,8 +652,10 @@ acc_get_principal(krb5_context context, int32_t error; cc_string_t name; - if (a->ccache == NULL) - return ENOENT; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } error = (*a->ccache->func->get_principal)(a->ccache, cc_credentials_v5, @@ -695,6 +678,11 @@ acc_get_first (krb5_context context, krb5_acc *a = ACACHE(id); int32_t error; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + error = (*a->ccache->func->new_credentials_iterator)(a->ccache, &iter); if (error) { krb5_clear_error_string(context); @@ -755,6 +743,11 @@ acc_remove_cred(krb5_context context, cc_int32 error; char *client, *server; + if (a->ccache == NULL) { + krb5_set_error_string(context, "No API credential found"); + return KRB5_CC_NOTFOUND; + } + if (cred->client) { ret = krb5_unparse_name(context, cred->client, &client); if (ret) @@ -894,12 +887,11 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) a = ACACHE(*id); a->ccache = cache; - a->cache_name = get_cc_name(a->ccache); - if (a->cache_name == NULL) { + error = get_cc_name(a); + if (error) { acc_close(context, *id); *id = NULL; - krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; + return translate_cc_error(context, error); } return 0; } @@ -917,6 +909,76 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } +static krb5_error_code +acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) +{ + krb5_acc *afrom = ACACHE(from); + krb5_acc *ato = ACACHE(to); + int32_t error; + + if (ato->ccache == NULL) { + cc_string_t name; + + error = (*afrom->ccache->func->get_principal)(afrom->ccache, + cc_credentials_v5, + &name); + if (error) + return translate_cc_error(context, error); + + error = (*ato->context->func->create_new_ccache)(ato->context, + cc_credentials_v5, + name->data, + &ato->ccache); + (*name->func->release)(name); + if (error) + return translate_cc_error(context, error); + } + + + error = (*ato->ccache->func->move)(afrom->ccache, ato->ccache); + return translate_cc_error(context, error); +} + +static krb5_error_code +acc_default_name(krb5_context context, char **str) +{ + krb5_error_code ret; + cc_context_t cc; + cc_string_t name; + int32_t error; + + ret = init_ccapi(context); + if (ret) + return ret; + + error = (*init_func)(&cc, ccapi_version_3, NULL, NULL); + if (error) + return translate_cc_error(context, error); + + error = (*cc->func->get_default_ccache_name)(cc, &name); + if (error) { + (*cc->func->release)(cc); + return translate_cc_error(context, error); + } + + asprintf(str, "API:%s", name->data); + (*name->func->release)(name); + (*cc->func->release)(cc); + + if (*str == NULL) { + krb5_set_error_string(context, "out of memory"); + return ENOMEM; + } + return 0; +} + + +/** + * Variable containing the API based credential cache implemention. + * + * @ingroup krb5_ccache + */ + const krb5_cc_ops krb5_acc_ops = { "API", acc_get_name, @@ -936,5 +998,7 @@ const krb5_cc_ops krb5_acc_ops = { acc_get_version, acc_get_cache_first, acc_get_cache_next, - acc_end_cache_get + acc_end_cache_get, + acc_move, + acc_default_name }; diff --git a/source4/heimdal/lib/krb5/add_et_list.c b/source4/heimdal/lib/krb5/add_et_list.c index a6005c6859..5455d8ac99 100644 --- a/source4/heimdal/lib/krb5/add_et_list.c +++ b/source4/heimdal/lib/krb5/add_et_list.c @@ -33,12 +33,20 @@ #include "krb5_locl.h" -RCSID("$Id: add_et_list.c 13713 2004-04-13 14:33:45Z lha $"); +RCSID("$Id: add_et_list.c 22603 2008-02-21 18:44:57Z lha $"); -/* +/** * Add a specified list of error messages to the et list in context. * Call func (probably a comerr-generated function) with a pointer to * the current et_list. + * + * @param context A kerberos context. + * @param func The generated com_err et function. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 */ krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c index 8c31843058..f364f5974d 100644 --- a/source4/heimdal/lib/krb5/addr_families.c +++ b/source4/heimdal/lib/krb5/addr_families.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c 18805 2006-10-22 06:54:00Z lha $"); +RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $"); struct addr_operations { int af; @@ -767,6 +767,19 @@ find_atype(int atype) return NULL; } +/** + * krb5_sockaddr2address stores a address a "struct sockaddr" sa in + * the krb5_address addr. + * + * @param context a Keberos context + * @param sa a struct sockaddr to extract the address from + * @param addr an Kerberos 5 address to store the address in. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_sockaddr2address (krb5_context context, const struct sockaddr *sa, krb5_address *addr) @@ -780,6 +793,20 @@ krb5_sockaddr2address (krb5_context context, return (*a->sockaddr2addr)(sa, addr); } +/** + * krb5_sockaddr2port extracts a port (if possible) from a "struct + * sockaddr. + * + * @param context a Keberos context + * @param sa a struct sockaddr to extract the port from + * @param port a pointer to an int16_t store the port in. + * + * @return Return an error code or 0. Will return + * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_sockaddr2port (krb5_context context, const struct sockaddr *sa, int16_t *port) @@ -793,6 +820,27 @@ krb5_sockaddr2port (krb5_context context, return (*a->sockaddr2port)(sa, port); } +/** + * krb5_addr2sockaddr sets the "struct sockaddr sockaddr" from addr + * and port. The argument sa_size should initially contain the size of + * the sa and after the call, it will contain the actual length of the + * address. In case of the sa is too small to fit the whole address, + * the up to *sa_size will be stored, and then *sa_size will be set to + * the required length. + * + * @param context a Keberos context + * @param addr the address to copy the from + * @param sa the struct sockaddr that will be filled in + * @param sa_size pointer to length of sa, and after the call, it will + * contain the actual length of the address. + * @param port set port in sa. + * + * @return Return an error code or 0. Will return + * KRB5_PROG_ATYPE_NOSUPP in case address type is not supported. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_addr2sockaddr (krb5_context context, const krb5_address *addr, @@ -808,7 +856,8 @@ krb5_addr2sockaddr (krb5_context context, return KRB5_PROG_ATYPE_NOSUPP; } if (a->addr2sockaddr == NULL) { - krb5_set_error_string (context, "Can't convert address type %d to sockaddr", + krb5_set_error_string (context, + "Can't convert address type %d to sockaddr", addr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } @@ -816,6 +865,15 @@ krb5_addr2sockaddr (krb5_context context, return 0; } +/** + * krb5_max_sockaddr_size returns the max size of the .Li struct + * sockaddr that the Kerberos library will return. + * + * @return Return an size_t of the maximum struct sockaddr. + * + * @ingroup krb5_address + */ + size_t KRB5_LIB_FUNCTION krb5_max_sockaddr_size (void) { @@ -828,6 +886,18 @@ krb5_max_sockaddr_size (void) return max_sockaddr_size; } +/** + * krb5_sockaddr_uninteresting returns TRUE for all .Fa sa that the + * kerberos library thinks are uninteresting. One example are link + * local addresses. + * + * @param sa pointer to struct sockaddr that might be interesting. + * + * @return Return a non zero for uninteresting addresses. + * + * @ingroup krb5_address + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_sockaddr_uninteresting(const struct sockaddr *sa) { @@ -837,6 +907,25 @@ krb5_sockaddr_uninteresting(const struct sockaddr *sa) return (*a->uninteresting)(sa); } +/** + * krb5_h_addr2sockaddr initializes a "struct sockaddr sa" from af and + * the "struct hostent" (see gethostbyname(3) ) h_addr_list + * component. The argument sa_size should initially contain the size + * of the sa, and after the call, it will contain the actual length of + * the address. + * + * @param context a Keberos context + * @param af addresses + * @param addr address + * @param sa returned struct sockaddr + * @param sa_size size of sa + * @param port port to set in sa. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_h_addr2sockaddr (krb5_context context, int af, @@ -853,6 +942,20 @@ krb5_h_addr2sockaddr (krb5_context context, return 0; } +/** + * krb5_h_addr2addr works like krb5_h_addr2sockaddr with the exception + * that it operates on a krb5_address instead of a struct sockaddr. + * + * @param context a Keberos context + * @param af address family + * @param haddr host address from struct hostent. + * @param addr returned krb5_address. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_h_addr2addr (krb5_context context, int af, @@ -866,6 +969,23 @@ krb5_h_addr2addr (krb5_context context, return (*a->h_addr2addr)(haddr, addr); } +/** + * krb5_anyaddr fills in a "struct sockaddr sa" that can be used to + * bind(2) to. The argument sa_size should initially contain the size + * of the sa, and after the call, it will contain the actual length + * of the address. + * + * @param context a Keberos context + * @param af address family + * @param sa sockaddr + * @param sa_size lenght of sa. + * @param port for to fill into sa. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_anyaddr (krb5_context context, int af, @@ -884,6 +1004,22 @@ krb5_anyaddr (krb5_context context, return 0; } +/** + * krb5_print_address prints the address in addr to the string string + * that have the length len. If ret_len is not NULL, it will be filled + * with the length of the string if size were unlimited (not including + * the final NUL) . + * + * @param addr address to be printed + * @param str pointer string to print the address into + * @param len length that will fit into area pointed to by "str". + * @param ret_len return length the str. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_print_address (const krb5_address *addr, char *str, size_t len, size_t *ret_len) @@ -921,6 +1057,19 @@ krb5_print_address (const krb5_address *addr, return 0; } +/** + * krb5_parse_address returns the resolved hostname in string to the + * krb5_addresses addresses . + * + * @param context a Keberos context + * @param string + * @param addresses + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_parse_address(krb5_context context, const char *string, @@ -980,6 +1129,21 @@ krb5_parse_address(krb5_context context, return 0; } +/** + * krb5_address_order compares the addresses addr1 and addr2 so that + * it can be used for sorting addresses. If the addresses are the same + * address krb5_address_order will return 0. Behavies like memcmp(2). + * + * @param context a Keberos context + * @param addr1 krb5_address to compare + * @param addr2 krb5_address to compare + * + * @return < 0 if address addr1 in "less" then addr2. 0 if addr1 and + * addr2 is the same address, > 0 if addr2 is "less" then addr1. + * + * @ingroup krb5_address + */ + int KRB5_LIB_FUNCTION krb5_address_order(krb5_context context, const krb5_address *addr1, @@ -1014,6 +1178,19 @@ krb5_address_order(krb5_context context, addr1->address.length); } +/** + * krb5_address_compare compares the addresses addr1 and addr2. + * Returns TRUE if the two addresses are the same. + * + * @param context a Keberos context + * @param addr1 address to compare + * @param addr2 address to compare + * + * @return Return an TRUE is the address are the same FALSE if not + * + * @ingroup krb5_address + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_address_compare(krb5_context context, const krb5_address *addr1, @@ -1022,6 +1199,19 @@ krb5_address_compare(krb5_context context, return krb5_address_order (context, addr1, addr2) == 0; } +/** + * krb5_address_search checks if the address addr is a member of the + * address set list addrlist . + * + * @param context a Keberos context. + * @param addr address to search for. + * @param addrlist list of addresses to look in for addr. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_address_search(krb5_context context, const krb5_address *addr, @@ -1035,6 +1225,18 @@ krb5_address_search(krb5_context context, return FALSE; } +/** + * krb5_free_address frees the data stored in the address that is + * alloced with any of the krb5_address functions. + * + * @param context a Keberos context + * @param address addresss to be freed. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_free_address(krb5_context context, krb5_address *address) @@ -1047,6 +1249,18 @@ krb5_free_address(krb5_context context, return 0; } +/** + * krb5_free_addresses frees the data stored in the address that is + * alloced with any of the krb5_address functions. + * + * @param context a Keberos context + * @param addresses addressses to be freed. + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_free_addresses(krb5_context context, krb5_addresses *addresses) @@ -1060,6 +1274,19 @@ krb5_free_addresses(krb5_context context, return 0; } +/** + * krb5_copy_address copies the content of address + * inaddr to outaddr. + * + * @param context a Keberos context + * @param inaddr pointer to source address + * @param outaddr pointer to destination address + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_address(krb5_context context, const krb5_address *inaddr, @@ -1071,6 +1298,19 @@ krb5_copy_address(krb5_context context, return copy_HostAddress(inaddr, outaddr); } +/** + * krb5_copy_addresses copies the content of addresses + * inaddr to outaddr. + * + * @param context a Keberos context + * @param inaddr pointer to source addresses + * @param outaddr pointer to destination addresses + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_addresses(krb5_context context, const krb5_addresses *inaddr, @@ -1085,6 +1325,19 @@ krb5_copy_addresses(krb5_context context, return 0; } +/** + * krb5_append_addresses adds the set of addresses in source to + * dest. While copying the addresses, duplicates are also sorted out. + * + * @param context a Keberos context + * @param dest destination of copy operation + * @param source adresses that are going to be added to dest + * + * @return Return an error code or 0. + * + * @ingroup krb5_address + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_append_addresses(krb5_context context, krb5_addresses *dest, @@ -1115,8 +1368,17 @@ krb5_append_addresses(krb5_context context, return 0; } -/* +/** * Create an address of type KRB5_ADDRESS_ADDRPORT from (addr, port) + * + * @param context a Keberos context + * @param res built address from addr/port + * @param addr address to use + * @param port port to use + * + * @return Return an error code or 0. + * + * @ingroup krb5_address */ krb5_error_code KRB5_LIB_FUNCTION @@ -1170,9 +1432,19 @@ krb5_make_addrport (krb5_context context, return 0; } -/* +/** * Calculate the boundary addresses of `inaddr'/`prefixlen' and store * them in `low' and `high'. + * + * @param context a Keberos context + * @param inaddr address in prefixlen that the bondery searched + * @param prefixlen width of boundery + * @param low lowest address + * @param high highest address + * + * @return Return an error code or 0. + * + * @ingroup krb5_address */ krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/asn1_glue.c b/source4/heimdal/lib/krb5/asn1_glue.c index 6b7d40d453..b3f775b4be 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 18269 2006-10-06 17:02:48Z lha $"); +RCSID("$Id: asn1_glue.c 21745 2007-07-31 16:11:25Z lha $"); krb5_error_code KRB5_LIB_FUNCTION _krb5_principal2principalname (PrincipalName *p, @@ -53,8 +53,12 @@ _krb5_principalname2krb5_principal (krb5_context context, const Realm realm) { krb5_principal p = malloc(sizeof(*p)); + if (p == NULL) + return ENOMEM; copy_PrincipalName(&from, &p->name); p->realm = strdup(realm); + if (p->realm == NULL) + return ENOMEM; *principal = p; return 0; } diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c index 5e08f15ad4..323f17a245 100644 --- a/source4/heimdal/lib/krb5/auth_context.c +++ b/source4/heimdal/lib/krb5/auth_context.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: auth_context.c 14452 2005-01-05 02:34:08Z lukeh $"); +RCSID("$Id: auth_context.c 21745 2007-07-31 16:11:25Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_auth_con_init(krb5_context context, @@ -141,14 +141,16 @@ krb5_auth_con_setaddrs(krb5_context context, if (auth_context->local_address) krb5_free_address (context, auth_context->local_address); else - auth_context->local_address = malloc(sizeof(krb5_address)); + if ((auth_context->local_address = malloc(sizeof(krb5_address))) == NULL) + return ENOMEM; krb5_copy_address(context, local_addr, auth_context->local_address); } if (remote_addr) { if (auth_context->remote_address) krb5_free_address (context, auth_context->remote_address); else - auth_context->remote_address = malloc(sizeof(krb5_address)); + if ((auth_context->remote_address = malloc(sizeof(krb5_address))) == NULL) + return ENOMEM; krb5_copy_address(context, remote_addr, auth_context->remote_address); } return 0; diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index 59aae40d28..5db6d2b2cf 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,12 +33,20 @@ #include "krb5_locl.h" -RCSID("$Id: cache.c 21498 2007-07-11 09:41:43Z lha $"); +RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $"); -/* +/** * Add a new ccache type with operations `ops', overwriting any * existing one if `override'. - * Return an error code or 0. + * + * @param context a Keberos context + * @param ops type of plugin symbol + * @param override flag to select if the registration is to overide + * an existing ops with the same name. + * + * @return Return an error code or 0. + * + * @ingroup krb5_ccache */ krb5_error_code KRB5_LIB_FUNCTION @@ -101,8 +109,7 @@ _krb5_cc_allocate(krb5_context context, /* * Allocate memory for a new ccache in `id' with operations `ops' - * and name `residual'. - * Return 0 or an error code. + * and name `residual'. Return 0 or an error code. */ static krb5_error_code @@ -122,12 +129,21 @@ allocate_ccache (krb5_context context, return ret; } -/* +/** * Find and allocate a ccache in `id' from the specification in `residual'. * If the ccache name doesn't contain any colon, interpret it as a file name. - * Return 0 or an error code. + * + * @param context a Keberos context. + * @param name string name of a credential cache. + * @param id return pointer to a found credential cache. + * + * @return Return 0 or an error code. In case of an error, id is set + * to NULL. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_resolve(krb5_context context, const char *name, @@ -135,6 +151,8 @@ krb5_cc_resolve(krb5_context context, { int i; + *id = NULL; + for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { size_t prefix_len = strlen(context->cc_ops[i].prefix); @@ -153,57 +171,64 @@ krb5_cc_resolve(krb5_context context, } } -/* +/** * Generate a new ccache of type `ops' in `id'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_gen_new(krb5_context context, const krb5_cc_ops *ops, krb5_ccache *id) { - krb5_error_code ret; - - ret = _krb5_cc_allocate(context, ops, id); - if (ret) - return ret; - return (*id)->ops->gen_new(context, id); + return krb5_cc_new_unique(context, ops->prefix, NULL, id); } -/* +/** * Generates a new unique ccache of `type` in `id'. If `type' is NULL, * the library chooses the default credential cache type. The supplied * `hint' (that can be NULL) is a string that the credential cache * type can use to base the name of the credential on, this is to make - * its easier for the user to differentiate the credentials. + * it easier for the user to differentiate the credentials. + * + * @return Returns 0 or an error code. * - * Returns 0 or an error code. + * @ingroup krb5_ccache */ krb5_error_code KRB5_LIB_FUNCTION krb5_cc_new_unique(krb5_context context, const char *type, const char *hint, krb5_ccache *id) { - const krb5_cc_ops *ops; - - if (type == NULL) - type = KRB5_DEFAULT_CCNAME; + const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE; + krb5_error_code ret; - ops = krb5_cc_get_prefix_ops(context, type); - if (ops == NULL) { - krb5_set_error_string(context, "Credential cache type %s is unknown", - type); - return KRB5_CC_UNKNOWN_TYPE; + if (type) { + ops = krb5_cc_get_prefix_ops(context, type); + if (ops == NULL) { + krb5_set_error_string(context, + "Credential cache type %s is unknown", type); + return KRB5_CC_UNKNOWN_TYPE; + } } - return krb5_cc_gen_new(context, ops, id); + ret = _krb5_cc_allocate(context, ops, id); + if (ret) + return ret; + return (*id)->ops->gen_new(context, id); } -/* +/** * Return the name of the ccache `id' + * + * @ingroup krb5_ccache */ + const char* KRB5_LIB_FUNCTION krb5_cc_get_name(krb5_context context, krb5_ccache id) @@ -211,10 +236,13 @@ krb5_cc_get_name(krb5_context context, return id->ops->get_name(context, id); } -/* +/** * Return the type of the ccache `id'. + * + * @ingroup krb5_ccache */ + const char* KRB5_LIB_FUNCTION krb5_cc_get_type(krb5_context context, krb5_ccache id) @@ -222,12 +250,15 @@ krb5_cc_get_type(krb5_context context, return id->ops->prefix; } -/* +/** * Return the complete resolvable name the ccache `id' in `str´. * `str` should be freed with free(3). * Returns 0 or an error (and then *str is set to NULL). + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_get_full_name(krb5_context context, krb5_ccache id, @@ -257,10 +288,13 @@ krb5_cc_get_full_name(krb5_context context, return 0; } -/* +/** * Return krb5_cc_ops of a the ccache `id'. + * + * @ingroup krb5_ccache */ + const krb5_cc_ops * krb5_cc_get_ops(krb5_context context, krb5_ccache id) { @@ -348,6 +382,10 @@ environment_changed(krb5_context context) { const char *e; + /* if the cc name was set, don't change it */ + if (context->default_cc_name_set) + return 0; + if(issuid()) return 0; @@ -367,10 +405,13 @@ environment_changed(krb5_context context) return 0; } -/* +/** * Set the default cc name for `context' to `name'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_set_default_name(krb5_context context, const char *name) { @@ -392,14 +433,23 @@ krb5_cc_set_default_name(krb5_context context, const char *name) if (e == NULL) { e = krb5_config_get_string(context, NULL, "libdefaults", "default_cc_name", NULL); - if (e == NULL) - e = KRB5_DEFAULT_CCNAME; - ret = _krb5_expand_default_cc_name(context, e, &p); - if (ret) - return ret; + if (e) { + ret = _krb5_expand_default_cc_name(context, e, &p); + if (ret) + return ret; + } + if (e == NULL) { + const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE; + ret = (*ops->default_name)(context, &p); + if (ret) + return ret; + } } - } else + context->default_cc_name_set = 0; + } else { p = strdup(name); + context->default_cc_name_set = 1; + } if (p == NULL) { krb5_set_error_string(context, "malloc - out of memory"); @@ -414,11 +464,16 @@ krb5_cc_set_default_name(krb5_context context, const char *name) return ret; } -/* +/** * Return a pointer to a context static string containing the default * ccache name. + * + * @return String to the default credential cache name. + * + * @ingroup krb5_ccache */ + const char* KRB5_LIB_FUNCTION krb5_cc_default_name(krb5_context context) { @@ -428,11 +483,15 @@ krb5_cc_default_name(krb5_context context) return context->default_cc_name; } -/* +/** * Open the default ccache in `id'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_default(krb5_context context, krb5_ccache *id) @@ -446,11 +505,15 @@ krb5_cc_default(krb5_context context, return krb5_cc_resolve(context, p, id); } -/* +/** * Create a new ccache in `id' for `primary_principal'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_initialize(krb5_context context, krb5_ccache id, @@ -460,11 +523,15 @@ krb5_cc_initialize(krb5_context context, } -/* +/** * Remove the ccache `id'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_destroy(krb5_context context, krb5_ccache id) @@ -476,11 +543,15 @@ krb5_cc_destroy(krb5_context context, return ret; } -/* +/** * Stop using the ccache `id' and free the related resources. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_close(krb5_context context, krb5_ccache id) @@ -491,11 +562,15 @@ krb5_cc_close(krb5_context context, return ret; } -/* +/** * Store `creds' in the ccache `id'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_store_cred(krb5_context context, krb5_ccache id, @@ -504,13 +579,17 @@ krb5_cc_store_cred(krb5_context context, return (*id->ops->store)(context, id, creds); } -/* +/** * Retrieve the credential identified by `mcreds' (and `whichfields') * from `id' in `creds'. 'creds' must be free by the caller using * krb5_free_cred_contents. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_retrieve_cred(krb5_context context, krb5_ccache id, @@ -526,7 +605,9 @@ krb5_cc_retrieve_cred(krb5_context context, mcreds, creds); } - krb5_cc_start_seq_get(context, id, &cursor); + ret = krb5_cc_start_seq_get(context, id, &cursor); + if (ret) + return ret; while((ret = krb5_cc_next_cred(context, id, &cursor, creds)) == 0){ if(krb5_compare_creds(context, whichfields, mcreds, creds)){ ret = 0; @@ -538,11 +619,15 @@ krb5_cc_retrieve_cred(krb5_context context, return ret; } -/* +/** * Return the principal of `id' in `principal'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_get_principal(krb5_context context, krb5_ccache id, @@ -551,12 +636,16 @@ krb5_cc_get_principal(krb5_context context, return (*id->ops->get_princ)(context, id, principal); } -/* +/** * Start iterating over `id', `cursor' is initialized to the * beginning. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_start_seq_get (krb5_context context, const krb5_ccache id, @@ -565,12 +654,16 @@ krb5_cc_start_seq_get (krb5_context context, return (*id->ops->get_first)(context, id, cursor); } -/* +/** * Retrieve the next cred pointed to by (`id', `cursor') in `creds' * and advance `cursor'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_next_cred (krb5_context context, const krb5_ccache id, @@ -580,7 +673,12 @@ krb5_cc_next_cred (krb5_context context, return (*id->ops->get_next)(context, id, cursor, creds); } -/* like krb5_cc_next_cred, but allow for selective retrieval */ +/** + * Like krb5_cc_next_cred, but allow for selective retrieval + * + * @ingroup krb5_ccache + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_next_cred_match(krb5_context context, @@ -601,10 +699,13 @@ krb5_cc_next_cred_match(krb5_context context, } } -/* +/** * Destroy the cursor `cursor'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_end_seq_get (krb5_context context, const krb5_ccache id, @@ -613,10 +714,13 @@ krb5_cc_end_seq_get (krb5_context context, return (*id->ops->end_get)(context, id, cursor); } -/* +/** * Remove the credential identified by `cred', `which' from `id'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_remove_cred(krb5_context context, krb5_ccache id, @@ -632,10 +736,13 @@ krb5_cc_remove_cred(krb5_context context, return (*id->ops->remove_cred)(context, id, which, cred); } -/* +/** * Set the flags of `id' to `flags'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_set_flags(krb5_context context, krb5_ccache id, @@ -644,10 +751,13 @@ krb5_cc_set_flags(krb5_context context, return (*id->ops->set_flags)(context, id, flags); } -/* +/** * Copy the contents of `from' to `to'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_copy_cache_match(krb5_context context, const krb5_ccache from, @@ -689,6 +799,13 @@ krb5_cc_copy_cache_match(krb5_context context, return ret; } +/** + * Just like krb5_cc_copy_cache_match, but copy everything. + * + * @ingroup krb5_ccache + */ + + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_copy_cache(krb5_context context, const krb5_ccache from, @@ -697,10 +814,13 @@ krb5_cc_copy_cache(krb5_context context, return krb5_cc_copy_cache_match(context, from, to, 0, NULL, NULL); } -/* +/** * Return the version of `id'. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_get_version(krb5_context context, const krb5_ccache id) @@ -711,23 +831,30 @@ krb5_cc_get_version(krb5_context context, return 0; } -/* +/** * Clear `mcreds' so it can be used with krb5_cc_retrieve_cred + * + * @ingroup krb5_ccache */ + void KRB5_LIB_FUNCTION krb5_cc_clear_mcred(krb5_creds *mcred) { memset(mcred, 0, sizeof(*mcred)); } -/* +/** * Get the cc ops that is registered in `context' to handle the * `prefix'. `prefix' can be a complete credential cache name or a * prefix, the function will only use part up to the first colon (:) - * if there is one. Returns NULL if ops not found. + * if there is one. + * Returns NULL if ops not found. + * + * @ingroup krb5_ccache */ + const krb5_cc_ops * krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) { @@ -761,12 +888,16 @@ struct krb5_cc_cache_cursor_data { krb5_cc_cursor cursor; }; -/* +/** * Start iterating over all caches of `type'. If `type' is NULL, the * default type is * used. `cursor' is initialized to the beginning. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_cache_get_first (krb5_context context, const char *type, @@ -807,12 +938,16 @@ krb5_cc_cache_get_first (krb5_context context, return ret; } -/* +/** * Retrieve the next cache pointed to by (`cursor') in `id' * and advance `cursor'. - * Return 0 or an error code. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_cache_next (krb5_context context, krb5_cc_cache_cursor cursor, @@ -821,10 +956,15 @@ krb5_cc_cache_next (krb5_context context, return cursor->ops->get_cache_next(context, cursor->cursor, id); } -/* +/** * Destroy the cursor `cursor'. + * + * @return Return 0 or an error code. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_cache_end_seq_get (krb5_context context, krb5_cc_cache_cursor cursor) @@ -836,14 +976,18 @@ krb5_cc_cache_end_seq_get (krb5_context context, return ret; } -/* +/** * Search for a matching credential cache of type `type' that have the * `principal' as the default principal. If NULL is used for `type', * the default type is used. On success, `id' needs to be freed with - * krb5_cc_close or krb5_cc_destroy. On failure, error code is - * returned and `id' is set to NULL. + * krb5_cc_close or krb5_cc_destroy. + * + * @return On failure, error code is returned and `id' is set to NULL. + * + * @ingroup krb5_ccache */ + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_cache_match (krb5_context context, krb5_principal client, @@ -895,3 +1039,35 @@ krb5_cc_cache_match (krb5_context context, return 0; } +/** + * Move the content from one credential cache to another. The + * operation is an atomic switch. + * + * @param context a Keberos context + * @param from the credential cache to move the content from + * @param to the credential cache to move the content to + + * @return On sucess, from is freed. On failure, error code is + * returned and from and to are both still allocated. + * + * @ingroup krb5_ccache + */ + +krb5_error_code +krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to) +{ + krb5_error_code ret; + + if (strcmp(from->ops->prefix, to->ops->prefix) != 0) { + krb5_set_error_string(context, "Moving credentials between diffrent " + "types not yet supported"); + return KRB5_CC_NOSUPP; + } + + ret = (*to->ops->move)(context, from, to); + if (ret == 0) { + memset(from, 0, sizeof(*from)); + free(from); + } + return ret; +} diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index b54e293a60..256783310e 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -34,12 +34,19 @@ #include "krb5_locl.h" #include -RCSID("$Id: context.c 19107 2006-11-24 14:24:33Z lha $"); +RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $"); #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ "libdefaults", F, NULL) +#define INIT_FLAG(C, O, V, D, F) \ + do { \ + if (krb5_config_get_bool_default((C), NULL, (D),"libdefaults", F, NULL)) { \ + (C)->O |= V; \ + } \ + } while(0) + /* * Set the list of etypes `ret_etypes' from the configuration variable * `name' @@ -181,11 +188,28 @@ 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, 1400, "large_message_size"); - INIT_FIELD(context, bool, dns_canonicalize_hostname, TRUE, "dns_canonicalize_hostname"); + INIT_FLAG(context, flags, KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME, TRUE, "dns_canonicalize_hostname"); + INIT_FLAG(context, flags, KRB5_CTX_F_CHECK_PAC, TRUE, "check_pac"); context->default_cc_name = NULL; + context->default_cc_name_set = 0; return 0; } +/** + * Initializes the context structure and reads the configuration file + * /etc/krb5.conf. The structure should be freed by calling + * krb5_free_context() when it is no longer being used. + * + * @param context pointer to returned context + * + * @return Returns 0 to indicate success. Otherwise an errno code is + * returned. Failure means either that something bad happened during + * initialization (typically ENOMEM) or that Kerberos should not be + * used ENXIO. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_init_context(krb5_context *context) { @@ -246,11 +270,21 @@ out: return ret; } +/** + * Frees the krb5_context allocated by krb5_init_context(). + * + * @param context context to be freed. + * + * @ingroup krb5 +*/ + void KRB5_LIB_FUNCTION krb5_free_context(krb5_context context) { if (context->default_cc_name) free(context->default_cc_name); + if (context->default_cc_name_env) + free(context->default_cc_name_env); free(context->etypes); free(context->etypes_des); krb5_free_host_realm (context, context->default_realms); @@ -272,6 +306,18 @@ krb5_free_context(krb5_context context) free(context); } +/** + * Reinit the context from a new set of filenames. + * + * @param context context to add configuration too. + * @param filenames array of filenames, end of list is indicated with a NULL filename. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_set_config_files(krb5_context context, char **filenames) { @@ -324,7 +370,7 @@ add_file(char ***pfilenames, int *len, char *file) } /* - * `pq' isn't free, its up the the caller + * `pq' isn't free, it's up the the caller */ krb5_error_code KRB5_LIB_FUNCTION @@ -380,6 +426,18 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp) return 0; } +/** + * Prepend the filename to the global configuration list. + * + * @param filelist a filename to add to the default list of filename + * @param pfilenames return array of filenames, should be freed with krb5_free_config_files(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_prepend_config_files_default(const char *filelist, char ***pfilenames) { @@ -399,6 +457,17 @@ krb5_prepend_config_files_default(const char *filelist, char ***pfilenames) return 0; } +/** + * Get the global configuration list. + * + * @param pfilenames return array of filenames, should be freed with krb5_free_config_files(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_get_default_config_files(char ***pfilenames) { @@ -414,6 +483,17 @@ krb5_get_default_config_files(char ***pfilenames) return krb5_prepend_config_files(files, NULL, pfilenames); } +/** + * Free a list of configuration files. + * + * @param filenames list to be freed. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_free_config_files(char **filenames) { @@ -423,12 +503,17 @@ krb5_free_config_files(char **filenames) free(filenames); } -/* +/** * 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. + * most preferred to least preferred encryption type. Note that some + * encryption types might be disabled, so you need to check with + * krb5_enctype_valid() before using the encryption type. + * + * @return list of enctypes, terminated with ETYPE_NULL. Its a static + * array completed into the Kerberos library so the content doesn't + * need to be freed. + * + * @ingroup krb5 */ const krb5_enctype * KRB5_LIB_FUNCTION @@ -479,6 +564,19 @@ default_etypes(krb5_context context, krb5_enctype **etype) return 0; } +/** + * Set the default encryption types that will be use in communcation + * with the KDC, clients and servers. + * + * @param context Kerberos 5 context. + * @param etypes Encryption types, array terminated with ETYPE_NULL (0). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_set_default_in_tkt_etypes(krb5_context context, const krb5_enctype *etypes) @@ -507,6 +605,19 @@ krb5_set_default_in_tkt_etypes(krb5_context context, return 0; } +/** + * Get the default encryption types that will be use in communcation + * with the KDC, clients and servers. + * + * @param context Kerberos 5 context. + * @param etypes Encryption types, array terminated with + * ETYPE_NULL(0), caller should free array with krb5_xfree(): + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ krb5_error_code KRB5_LIB_FUNCTION krb5_get_default_in_tkt_etypes(krb5_context context, @@ -534,6 +645,18 @@ krb5_get_default_in_tkt_etypes(krb5_context context, return 0; } +/** + * Return the error string for the error code. The caller must not + * free the string. + * + * @param context Kerberos 5 context. + * @param code Kerberos error code. + * + * @return the error message matching code + * + * @ingroup krb5 + */ + const char* KRB5_LIB_FUNCTION krb5_get_err_text(krb5_context context, krb5_error_code code) { @@ -547,6 +670,14 @@ krb5_get_err_text(krb5_context context, krb5_error_code code) return p; } +/** + * Init the built-in ets in the Kerberos library. + * + * @param context kerberos context to add the ets too + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_init_ets(krb5_context context) { @@ -561,18 +692,50 @@ krb5_init_ets(krb5_context context) } } +/** + * Make the kerberos library default to the admin KDC. + * + * @param context Kerberos 5 context. + * @param flag boolean flag to select if the use the admin KDC or not. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_set_use_admin_kdc (krb5_context context, krb5_boolean flag) { context->use_admin_kdc = flag; } +/** + * Make the kerberos library default to the admin KDC. + * + * @param context Kerberos 5 context. + * + * @return boolean flag to telling the context will use admin KDC as the default KDC. + * + * @ingroup krb5 + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_get_use_admin_kdc (krb5_context context) { return context->use_admin_kdc; } +/** + * Add extra address to the address list that the library will add to + * the client's address list when communicating with the KDC. + * + * @param context Kerberos 5 context. + * @param addresses addreses to add + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses) { @@ -584,6 +747,19 @@ krb5_add_extra_addresses(krb5_context context, krb5_addresses *addresses) return krb5_set_extra_addresses(context, addresses); } +/** + * Set extra address to the address list that the library will add to + * the client's address list when communicating with the KDC. + * + * @param context Kerberos 5 context. + * @param addresses addreses to set + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses) { @@ -607,6 +783,19 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses) return krb5_copy_addresses(context, addresses, context->extra_addresses); } +/** + * Get extra address to the address list that the library will add to + * the client's address list when communicating with the KDC. + * + * @param context Kerberos 5 context. + * @param addresses addreses to set + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses) { @@ -617,6 +806,19 @@ krb5_get_extra_addresses(krb5_context context, krb5_addresses *addresses) return krb5_copy_addresses(context,context->extra_addresses, addresses); } +/** + * Add extra addresses to ignore when fetching addresses from the + * underlaying operating system. + * + * @param context Kerberos 5 context. + * @param addresses addreses to ignore + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses) { @@ -628,6 +830,19 @@ krb5_add_ignore_addresses(krb5_context context, krb5_addresses *addresses) return krb5_set_ignore_addresses(context, addresses); } +/** + * Set extra addresses to ignore when fetching addresses from the + * underlaying operating system. + * + * @param context Kerberos 5 context. + * @param addresses addreses to ignore + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses) { @@ -650,6 +865,19 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses) return krb5_copy_addresses(context, addresses, context->ignore_addresses); } +/** + * Get extra addresses to ignore when fetching addresses from the + * underlaying operating system. + * + * @param context Kerberos 5 context. + * @param addresses list addreses ignored + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses) { @@ -660,6 +888,18 @@ krb5_get_ignore_addresses(krb5_context context, krb5_addresses *addresses) return krb5_copy_addresses(context, context->ignore_addresses, addresses); } +/** + * Set version of fcache that the library should use. + * + * @param context Kerberos 5 context. + * @param version version number. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_set_fcache_version(krb5_context context, int version) { @@ -667,6 +907,18 @@ krb5_set_fcache_version(krb5_context context, int version) return 0; } +/** + * Get version of fcache that the library should use. + * + * @param context Kerberos 5 context. + * @param version version number. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_get_fcache_version(krb5_context context, int *version) { @@ -674,6 +926,15 @@ krb5_get_fcache_version(krb5_context context, int *version) return 0; } +/** + * Runtime check if the Kerberos library was complied with thread support. + * + * @return TRUE if the library was compiled with thread support, FALSE if not. + * + * @ingroup krb5 + */ + + krb5_boolean KRB5_LIB_FUNCTION krb5_is_thread_safe(void) { @@ -684,18 +945,52 @@ krb5_is_thread_safe(void) #endif } +/** + * Set if the library should use DNS to canonicalize hostnames. + * + * @param context Kerberos 5 context. + * @param flag if its dns canonicalizion is used or not. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_set_dns_canonicalize_hostname (krb5_context context, krb5_boolean flag) { - context->dns_canonicalize_hostname = flag; + if (flag) + context->flags |= KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME; + else + context->flags &= ~KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME; } +/** + * Get if the library uses DNS to canonicalize hostnames. + * + * @param context Kerberos 5 context. + * + * @return return non zero if the library uses DNS to canonicalize hostnames. + * + * @ingroup krb5 + */ + krb5_boolean KRB5_LIB_FUNCTION krb5_get_dns_canonicalize_hostname (krb5_context context) { - return context->dns_canonicalize_hostname; + return (context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) ? 1 : 0; } +/** + * Get current offset in time to the KDC. + * + * @param context Kerberos 5 context. + * @param sec seconds part of offset. + * @param usec micro seconds part of offset. + * + * @return return non zero if the library uses DNS to canonicalize hostnames. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) { @@ -706,12 +1001,31 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) return 0; } +/** + * Get max time skew allowed. + * + * @param context Kerberos 5 context. + * + * @return timeskew in seconds. + * + * @ingroup krb5 + */ + time_t KRB5_LIB_FUNCTION krb5_get_max_time_skew (krb5_context context) { return context->max_skew; } +/** + * Set max time skew allowed. + * + * @param context Kerberos 5 context. + * @param t timeskew in seconds. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_set_max_time_skew (krb5_context context, time_t t) { diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c index 1d1b4d7070..b2af0187ea 100644 --- a/source4/heimdal/lib/krb5/convert_creds.c +++ b/source4/heimdal/lib/krb5/convert_creds.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: convert_creds.c 14897 2005-04-23 19:40:57Z lha $"); +RCSID("$Id: convert_creds.c 22050 2007-11-11 11:20:46Z lha $"); #include "krb5-v4compat.h" @@ -42,10 +42,20 @@ check_ticket_flags(TicketFlags f) return 0; /* maybe add some more tests here? */ } -/* Convert the v5 credentials in `in_cred' to v4-dito in `v4creds'. - * This is done by sending them to the 524 function in the KDC. If +/** + * Convert the v5 credentials in in_cred to v4-dito in v4creds. This + * is done by sending them to the 524 function in the KDC. If * `in_cred' doesn't contain a DES session key, then a new one is * gotten from the KDC and stored in the cred cache `ccache'. + * + * @param context Kerberos 5 context. + * @param in_cred the credential to convert + * @param v4creds the converted credential + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5_v4compat */ krb5_error_code KRB5_LIB_FUNCTION @@ -134,6 +144,21 @@ out2: return ret; } +/** + * Convert the v5 credentials in in_cred to v4-dito in v4creds, + * check the credential cache ccache before checking with the KDC. + * + * @param context Kerberos 5 context. + * @param ccache credential cache used to check for des-ticket. + * @param in_cred the credential to convert + * @param v4creds the converted credential + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5_v4compat + */ + krb5_error_code KRB5_LIB_FUNCTION krb524_convert_creds_kdc_ccache(krb5_context context, krb5_ccache ccache, diff --git a/source4/heimdal/lib/krb5/copy_host_realm.c b/source4/heimdal/lib/krb5/copy_host_realm.c index 4e668c2a14..8c4f39b4ac 100644 --- a/source4/heimdal/lib/krb5/copy_host_realm.c +++ b/source4/heimdal/lib/krb5/copy_host_realm.c @@ -33,10 +33,19 @@ #include "krb5_locl.h" -RCSID("$Id: copy_host_realm.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $"); -/* +/** * Copy the list of realms from `from' to `to'. + * + * @param context Kerberos 5 context. + * @param from list of realms to copy from. + * @param to list of realms to copy to, free list of krb5_free_host_realm(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 */ krb5_error_code KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index d4d83162f1..17ef46dfa3 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -33,15 +33,30 @@ #include "krb5_locl.h" -RCSID("$Id: creds.c 15167 2005-05-18 04:21:57Z lha $"); +RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $"); + +#undef __attribute__ +#define __attribute__(X) /* keep this for compatibility with older code */ -krb5_error_code KRB5_LIB_FUNCTION +krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c) { return krb5_free_cred_contents (context, c); } +/** + * Free content of krb5_creds. + * + * @param context Kerberos 5 context. + * @param c krb5_creds to free. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_free_cred_contents (krb5_context context, krb5_creds *c) { @@ -58,6 +73,19 @@ krb5_free_cred_contents (krb5_context context, krb5_creds *c) return 0; } +/** + * Copy content of krb5_creds. + * + * @param context Kerberos 5 context. + * @param incred source credential + * @param c destination credential, free with krb5_free_cred_contents(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_creds_contents (krb5_context context, const krb5_creds *incred, @@ -102,6 +130,19 @@ fail: return ret; } +/** + * Copy krb5_creds. + * + * @param context Kerberos 5 context. + * @param incred source credential + * @param outcred destination credential, free with krb5_free_creds(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_creds (krb5_context context, const krb5_creds *incred, @@ -119,6 +160,18 @@ krb5_copy_creds (krb5_context context, return krb5_copy_creds_contents (context, incred, c); } +/** + * Free krb5_creds. + * + * @param context Kerberos 5 context. + * @param c krb5_creds to free. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_free_creds (krb5_context context, krb5_creds *c) { @@ -127,15 +180,7 @@ krb5_free_creds (krb5_context context, krb5_creds *c) return 0; } -/* XXX these do not belong here */ -static krb5_boolean -krb5_data_equal(const krb5_data *a, const krb5_data *b) -{ - if(a->length != b->length) - return FALSE; - return memcmp(a->data, b->data, a->length) == 0; -} - +/* XXX this do not belong here */ static krb5_boolean krb5_times_equal(const krb5_times *a, const krb5_times *b) { @@ -145,9 +190,18 @@ krb5_times_equal(const krb5_times *a, const krb5_times *b) a->renew_till == b->renew_till; } -/* +/** * Return TRUE if `mcreds' and `creds' are equal (`whichfields' * determines what equal means). + * + * @param context Kerberos 5 context. + * @param whichfields which fields to compare. + * @param mcreds cred to compare with. + * @param creds cred to compare with. + * + * @return return TRUE if mcred and creds are equal, FALSE if not. + * + * @ingroup krb5 */ krb5_boolean KRB5_LIB_FUNCTION @@ -201,11 +255,11 @@ krb5_compare_creds(krb5_context context, krb5_flags whichfields, for(i = 0; match && i < mcreds->authdata.len; i++) match = (mcreds->authdata.val[i].ad_type == creds->authdata.val[i].ad_type) && - krb5_data_equal(&mcreds->authdata.val[i].ad_data, - &creds->authdata.val[i].ad_data); + (krb5_data_cmp(&mcreds->authdata.val[i].ad_data, + &creds->authdata.val[i].ad_data) == 0); } if (match && (whichfields & KRB5_TC_MATCH_2ND_TKT)) - match = krb5_data_equal(&mcreds->second_ticket, &creds->second_ticket); + match = (krb5_data_cmp(&mcreds->second_ticket, &creds->second_ticket) == 0); if (match && (whichfields & KRB5_TC_MATCH_IS_SKEY)) match = ((mcreds->second_ticket.length == 0) == diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 12f75d0bcd..2e63490946 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 21130 2007-06-18 20:45:21Z lha $"); +RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $"); #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -184,7 +184,7 @@ krb5_DES_schedule(krb5_context context, #ifdef ENABLE_AFS_STRING_TO_KEY /* This defines the Andrew string_to_key function. It accepts a password - * string as input and converts its via a one-way encryption algorithm to a DES + * string as input and converts it via a one-way encryption algorithm to a DES * encryption key. It is compatible with the original Andrew authentication * service password database. */ @@ -425,6 +425,7 @@ DES3_string_to_key(krb5_context context, size_t len; unsigned char tmp[24]; DES_cblock keys[3]; + krb5_error_code ret; len = password.length + salt.saltvalue.length; str = malloc(len); @@ -439,7 +440,13 @@ DES3_string_to_key(krb5_context context, DES_key_schedule s[3]; int i; - _krb5_n_fold(str, len, tmp, 24); + ret = _krb5_n_fold(str, len, tmp, 24); + if (ret) { + memset(str, 0, len); + free(str); + krb5_set_error_string(context, "out of memory"); + return ret; + } for(i = 0; i < 3; i++){ memcpy(keys + i, tmp + i * 8, sizeof(keys[i])); @@ -557,12 +564,14 @@ ARCFOUR_string_to_key(krb5_context context, size_t len; int i; MD4_CTX m; + krb5_error_code ret; len = 2 * password.length; s = malloc (len); if (len != 0 && s == NULL) { krb5_set_error_string(context, "malloc: out of memory"); - return ENOMEM; + ret = ENOMEM; + goto out; } for (p = s, i = 0; i < password.length; ++i) { *p++ = ((char *)password.data)[i]; @@ -571,11 +580,17 @@ ARCFOUR_string_to_key(krb5_context context, MD4_Init (&m); MD4_Update (&m, s, len); key->keytype = enctype; - krb5_data_alloc (&key->keyvalue, 16); + ret = krb5_data_alloc (&key->keyvalue, 16); + if (ret) { + krb5_set_error_string(context, "malloc: out of memory"); + goto out; + } MD4_Final (key->keyvalue.data, &m); memset (s, 0, len); + ret = 0; +out: free (s); - return 0; + return ret; } /* @@ -1829,7 +1844,9 @@ create_checksum (krb5_context context, } else dkey = NULL; result->cksumtype = ct->type; - krb5_data_alloc(&result->checksum, ct->checksumsize); + ret = krb5_data_alloc(&result->checksum, ct->checksumsize); + if (ret) + return (ret); (*ct->checksum)(context, dkey, data, len, usage, result); return 0; } @@ -2751,6 +2768,7 @@ krb5_enctype_to_string(krb5_context context, if(e == NULL) { krb5_set_error_string (context, "encryption type %d not supported", etype); + *string = NULL; return KRB5_PROG_ETYPE_NOSUPP; } *string = strdup(e->name); @@ -3525,15 +3543,19 @@ derive_key(krb5_context context, ret = _key_schedule(context, key); if(ret) return ret; - if(et->blocksize * 8 < kt->bits || - len != et->blocksize) { + if(et->blocksize * 8 < kt->bits || len != et->blocksize) { nblocks = (kt->bits + et->blocksize * 8 - 1) / (et->blocksize * 8); k = malloc(nblocks * et->blocksize); if(k == NULL) { krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - _krb5_n_fold(constant, len, k, et->blocksize); + ret = _krb5_n_fold(constant, len, k, et->blocksize); + if (ret) { + free(k); + krb5_set_error_string(context, "out of memory"); + return ret; + } for(i = 0; i < nblocks; i++) { if(i > 0) memcpy(k + i * et->blocksize, @@ -3559,7 +3581,12 @@ derive_key(krb5_context context, krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } - _krb5_n_fold(c, len, k, res_len); + ret = _krb5_n_fold(c, len, k, res_len); + if (ret) { + free(k); + krb5_set_error_string(context, "out of memory"); + return ret; + } free(c); } @@ -3821,7 +3848,12 @@ krb5_string_to_key_derived(krb5_context context, krb5_set_error_string (context, "malloc: out of memory"); return ENOMEM; } - _krb5_n_fold(str, len, tmp, keylen); + ret = _krb5_n_fold(str, len, tmp, keylen); + if (ret) { + free(tmp); + krb5_set_error_string(context, "out of memory"); + return ret; + } kd.schedule = NULL; DES3_postproc (context, tmp, keylen, &kd); /* XXX */ memset(tmp, 0, keylen); @@ -4122,7 +4154,7 @@ main() d = _new_derived_key(crypto, usage); if(d == NULL) - return ENOMEM; + krb5_errx(context, 1, "_new_derived_key failed"); krb5_copy_keyblock(context, crypto->key.key, &d->key); _krb5_put_int(constant, usage, 4); derive_key(context, crypto->et, d, constant, sizeof(constant)); @@ -4148,11 +4180,10 @@ main() "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"; */ key.keyvalue.length = 4; - d = calloc(1, sizeof(*d)); - + d = ecalloc(1, sizeof(*d)); d->key = &key; res.checksum.length = 20; - res.checksum.data = malloc(res.checksum.length); + res.checksum.data = emalloc(res.checksum.length); SP_HMAC_SHA1_checksum(context, d, data, 28, &res); return 0; diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index 2ece85bdb3..eda1a8b259 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,15 @@ #include "krb5_locl.h" -RCSID("$Id: data.c 20039 2007-01-23 20:34:01Z lha $"); +RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $"); + +/** + * Reset the (potentially uninitalized) krb5_data structure. + * + * @param p krb5_data to reset. + * + * @ingroup krb5 + */ void KRB5_LIB_FUNCTION krb5_data_zero(krb5_data *p) @@ -42,6 +50,15 @@ krb5_data_zero(krb5_data *p) p->data = NULL; } +/** + * Free the content of krb5_data structure, its ok to free a zeroed + * structure. When done, the structure will be zeroed. + * + * @param p krb5_data to free. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_data_free(krb5_data *p) { @@ -50,12 +67,30 @@ krb5_data_free(krb5_data *p) krb5_data_zero(p); } +/** + * Same as krb5_data_free(). + * + * @param context Kerberos 5 context. + * @param data krb5_data to free. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_free_data_contents(krb5_context context, krb5_data *data) { krb5_data_free(data); } +/** + * Free krb5_data (and its content). + * + * @param context Kerberos 5 context. + * @param p krb5_data to free. + * + * @ingroup krb5 + */ + void KRB5_LIB_FUNCTION krb5_free_data(krb5_context context, krb5_data *p) @@ -64,6 +99,18 @@ krb5_free_data(krb5_context context, free(p); } +/** + * Allocate data of and krb5_data. + * + * @param p krb5_data to free. + * @param len size to allocate. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_data_alloc(krb5_data *p, int len) { @@ -74,6 +121,18 @@ krb5_data_alloc(krb5_data *p, int len) return 0; } +/** + * Grow (or shrink) the content of krb5_data to a new size. + * + * @param p krb5_data to free. + * @param len new size. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_data_realloc(krb5_data *p, int len) { @@ -86,6 +145,19 @@ krb5_data_realloc(krb5_data *p, int len) return 0; } +/** + * Copy the data of len into the krb5_data. + * + * @param p krb5_data to copy into. + * @param data data to copy.. + * @param len new size. + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_data_copy(krb5_data *p, const void *data, size_t len) { @@ -99,6 +171,19 @@ krb5_data_copy(krb5_data *p, const void *data, size_t len) return 0; } +/** + * Copy the data into a newly allocated krb5_data. + * + * @param context Kerberos 5 context. + * @param indata the krb5_data data to copy + * @param outdata new krb5_date to copy too. Free with krb5_free_data(). + * + * @return Returns 0 to indicate success. Otherwise an kerberos et + * error code is returned. + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_copy_data(krb5_context context, const krb5_data *indata, @@ -119,6 +204,17 @@ krb5_copy_data(krb5_context context, return ret; } +/** + * Compare to data. + * + * @param data1 krb5_data to compare + * @param data2 krb5_data to compare + * + * @return return the same way as memcmp(), useful when sorting. + * + * @ingroup krb5 + */ + int KRB5_LIB_FUNCTION krb5_data_cmp(const krb5_data *data1, const krb5_data *data2) { diff --git a/source4/heimdal/lib/krb5/eai_to_heim_errno.c b/source4/heimdal/lib/krb5/eai_to_heim_errno.c index c6b5cfb18b..19315cea86 100644 --- a/source4/heimdal/lib/krb5/eai_to_heim_errno.c +++ b/source4/heimdal/lib/krb5/eai_to_heim_errno.c @@ -33,12 +33,17 @@ #include -RCSID("$Id: eai_to_heim_errno.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: eai_to_heim_errno.c 22065 2007-11-11 16:41:06Z lha $"); -/* - * convert the getaddrinfo error code in `eai_errno' into a - * krb5_error_code. `system_error' should have the value of the errno - * after the failed call. +/** + * Convert the getaddrinfo() error code to a Kerberos et error code. + * + * @param eai_errno contains the error code from getaddrinfo(). + * @param system_error should have the value of errno after the failed getaddrinfo(). + * + * @return Kerberos error code representing the EAI errors. + * + * @ingroup krb5_error */ krb5_error_code KRB5_LIB_FUNCTION @@ -78,6 +83,17 @@ krb5_eai_to_heim_errno(int eai_errno, int system_error) } } +/** + * Convert the gethostname() error code (h_error) to a Kerberos et + * error code. + * + * @param eai_errno contains the error code from gethostname(). + * + * @return Kerberos error code representing the gethostname errors. + * + * @ingroup krb5_error + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_h_errno_to_heim_errno(int eai_errno) { diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index 1ba6494487..ff6e98a3dc 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: error_string.c 16746 2006-02-16 07:49:23Z lha $"); +RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $"); #undef __attribute__ #define __attribute__(X) @@ -86,14 +86,26 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) return 0; } +/** + * Return the error message in context. On error or no error string, + * the function returns NULL. + * + * @param context Kerberos 5 context + * + * @return an error string, needs to be freed with + * krb5_free_error_string(). The functions return NULL on error. + * + * @ingroup krb5_error + */ + char * KRB5_LIB_FUNCTION krb5_get_error_string(krb5_context context) { - char *ret; + char *ret = NULL; HEIMDAL_MUTEX_lock(context->mutex); - ret = context->error_string; - context->error_string = NULL; + if (context->error_string) + ret = strdup(context->error_string); HEIMDAL_MUTEX_unlock(context->mutex); return ret; } @@ -108,6 +120,19 @@ krb5_have_error_string(krb5_context context) return str != NULL; } +/** + * Return the error message for `code' in context. On error the + * function returns NULL. + * + * @param context Kerberos 5 context + * @param code Error code related to the error + * + * @return an error string, needs to be freed with + * krb5_free_error_string(). The functions return NULL on error. + * + * @ingroup krb5_error + */ + char * KRB5_LIB_FUNCTION krb5_get_error_message(krb5_context context, krb5_error_code code) { diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c index b2b410269e..28e39afb42 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 18906 2006-11-04 03:34:57Z lha $"); +RCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $"); static krb5_error_code copy_hostname(krb5_context context, @@ -62,7 +62,7 @@ krb5_expand_hostname (krb5_context context, struct addrinfo *ai, *a, hints; int error; - if (!context->dns_canonicalize_hostname) + if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) return copy_hostname (context, orig_hostname, new_hostname); memset (&hints, 0, sizeof(hints)); @@ -127,7 +127,7 @@ krb5_expand_hostname_realms (krb5_context context, int error; krb5_error_code ret = 0; - if (!context->dns_canonicalize_hostname) + if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) return vanilla_hostname (context, orig_hostname, new_hostname, realms); diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index 864efa8d7d..484df059ab 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2004 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: fcache.c 19379 2006-12-15 21:35:52Z lha $"); +RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $"); typedef struct krb5_fcache{ char *filename; @@ -108,7 +108,7 @@ int _krb5_xunlock(krb5_context context, int fd) { int ret; -#ifdef HAVE_FCNTL_LOCK +#ifdef HAVE_FCNTL struct flock l; l.l_start = 0; l.l_len = 0; @@ -463,9 +463,13 @@ init_fcc (krb5_context context, krb5_storage_set_eof_code(sp, KRB5_CC_END); ret = krb5_ret_int8(sp, &pvno); if(ret != 0) { - if(ret == KRB5_CC_END) - ret = ENOENT; /* empty file */ - krb5_clear_error_string(context); + if(ret == KRB5_CC_END) { + krb5_set_error_string(context, "Empty credential cache file: %s", + FILENAME(id)); + ret = ENOENT; + } else + krb5_set_error_string(context, "Error reading pvno in " + "cache file: %s", FILENAME(id)); goto out; } if(pvno != 5) { @@ -476,7 +480,8 @@ init_fcc (krb5_context context, } ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */ if(ret != 0) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading tag in " + "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } @@ -489,7 +494,8 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &length); if(ret) { ret = KRB5_CC_FORMAT; - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading tag length in " + "cache file: %s", FILENAME(id)); goto out; } while(length > 0) { @@ -499,13 +505,15 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &dtag); if(ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading dtag in " + "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } ret = krb5_ret_int16 (sp, &data_len); if(ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading dlength in " + "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } @@ -513,13 +521,15 @@ init_fcc (krb5_context context, case FCC_TAG_DELTATIME : ret = krb5_ret_int32 (sp, &context->kdc_sec_offset); if(ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading kdc_sec in " + "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } ret = krb5_ret_int32 (sp, &context->kdc_usec_offset); if(ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading kdc_usec in " + "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } @@ -528,7 +538,9 @@ init_fcc (krb5_context context, for (i = 0; i < data_len; ++i) { ret = krb5_ret_int8 (sp, &dummy); if(ret) { - krb5_clear_error_string(context); + krb5_set_error_string(context, "Error reading unknown " + "tag in cache file: %s", + FILENAME(id)); ret = KRB5_CC_FORMAT; goto out; } @@ -755,6 +767,95 @@ fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } +static krb5_error_code +fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) +{ + krb5_error_code ret = 0; + + ret = rename(FILENAME(from), FILENAME(to)); + if (ret && errno != EXDEV) { + ret = errno; + krb5_set_error_string(context, + "Rename of file from %s to %s failed: %s", + FILENAME(from), FILENAME(to), + strerror(ret)); + return ret; + } else if (ret && errno == EXDEV) { + /* make a copy and delete the orignal */ + krb5_ssize_t sz1, sz2; + int fd1, fd2; + char buf[BUFSIZ]; + + ret = fcc_open(context, from, &fd1, O_RDONLY | O_BINARY, 0); + if(ret) + return ret; + + unlink(FILENAME(to)); + + ret = fcc_open(context, to, &fd2, + O_WRONLY | O_CREAT | O_EXCL | O_BINARY, 0600); + if(ret) + goto out1; + + while((sz1 = read(fd1, buf, sizeof(buf))) > 0) { + sz2 = write(fd2, buf, sz1); + if (sz1 != sz2) { + ret = EIO; + krb5_set_error_string(context, + "Failed to write data from one file " + "credential cache to the other"); + goto out2; + } + } + if (sz1 < 0) { + ret = EIO; + krb5_set_error_string(context, + "Failed to read data from one file " + "credential cache to the other"); + goto out2; + } + erase_file(FILENAME(from)); + + out2: + fcc_unlock(context, fd2); + close(fd2); + + out1: + fcc_unlock(context, fd1); + close(fd1); + + if (ret) { + erase_file(FILENAME(to)); + return ret; + } + } + + /* make sure ->version is uptodate */ + { + krb5_storage *sp; + int fd; + ret = init_fcc (context, to, &sp, &fd); + krb5_storage_free(sp); + fcc_unlock(context, fd); + close(fd); + } + return ret; +} + +static krb5_error_code +fcc_default_name(krb5_context context, char **str) +{ + return _krb5_expand_default_cc_name(context, + KRB5_DEFAULT_CCNAME_FILE, + str); +} + +/** + * Variable containing the FILE based credential cache implemention. + * + * @ingroup krb5_ccache + */ + const krb5_cc_ops krb5_fcc_ops = { "FILE", fcc_get_name, @@ -774,5 +875,7 @@ const krb5_cc_ops krb5_fcc_ops = { fcc_get_version, fcc_get_cache_first, fcc_get_cache_next, - fcc_end_cache_get + fcc_end_cache_get, + fcc_move, + fcc_default_name }; diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 7c3f128ae5..fc78945c63 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: get_cred.c 21669 2007-07-22 11:29:13Z lha $"); +RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -761,14 +761,6 @@ get_cred_from_kdc_flags(krb5_context context, try_realm = krb5_config_get_string(context, NULL, "capaths", client_realm, server_realm, NULL); - -#if 1 - /* XXX remove in future release */ - if(try_realm == NULL) - try_realm = krb5_config_get_string(context, NULL, "libdefaults", - "capath", server_realm, NULL); -#endif - if (try_realm == NULL) try_realm = client_realm; diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index 1bb98737d1..cb8b7c8641 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: get_for_creds.c 17036 2006-04-10 09:28:15Z lha $"); +RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $"); static krb5_error_code add_addrs(krb5_context context, @@ -83,11 +83,23 @@ fail: return ret; } -/* - * Forward credentials for `client' to host `hostname`, - * making them forwardable if `forwardable', and returning the - * blob of data to sent in `out_data'. - * If hostname == NULL, pick it from `server' +/** + * Forward credentials for client to host hostname , making them + * forwardable if forwardable, and returning the blob of data to sent + * in out_data. If hostname == NULL, pick it from server. + * + * @param context A kerberos 5 context. + * @param auth_context the auth context with the key to encrypt the out_data. + * @param hostname the host to forward the tickets too. + * @param client the client to delegate from. + * @param server the server to delegate the credential too. + * @param ccache credential cache to use. + * @param forwardable make the forwarded ticket forwabledable. + * @param out_data the resulting credential. + * + * @return Return an error code or 0. + * + * @ingroup krb5_credential */ krb5_error_code KRB5_LIB_FUNCTION @@ -147,8 +159,31 @@ krb5_fwd_tgt_creds (krb5_context context, return ret; } -/* +/** + * Gets tickets forwarded to hostname. If the tickets that are + * forwarded are address-less, the forwarded tickets will also be + * address-less. + * + * If the ticket have any address, hostname will be used for figure + * out the address to forward the ticket too. This since this might + * use DNS, its insecure and also doesn't represent configured all + * addresses of the host. For example, the host might have two + * adresses, one IPv4 and one IPv6 address where the later is not + * published in DNS. This IPv6 address might be used communications + * and thus the resulting ticket useless. * + * @param context A kerberos 5 context. + * @param auth_context the auth context with the key to encrypt the out_data. + * @param ccache credential cache to use + * @param flags the flags to control the resulting ticket flags + * @param hostname the host to forward the tickets too. + * @param in_creds the in client and server ticket names. The client + * and server components forwarded to the remote host. + * @param out_data the resulting credential. + * + * @return Return an error code or 0. + * + * @ingroup krb5_credential */ krb5_error_code KRB5_LIB_FUNCTION @@ -174,39 +209,31 @@ krb5_get_forwarded_creds (krb5_context context, struct addrinfo *ai; int save_errno; krb5_creds *ticket; - char *realm; - - realm = in_creds->client->realm; + paddrs = NULL; addrs.len = 0; addrs.val = NULL; - paddrs = &addrs; - { + ret = krb5_get_credentials(context, 0, ccache, in_creds, &ticket); + if(ret == 0) { + if (ticket->addresses.len) + paddrs = &addrs; + krb5_free_creds (context, ticket); + } else { krb5_boolean noaddr; - krb5_appdefault_boolean(context, NULL, realm, + krb5_appdefault_boolean(context, NULL, + krb5_principal_get_realm(context, + in_creds->client), "no-addresses", KRB5_ADDRESSLESS_DEFAULT, &noaddr); - if (noaddr) - paddrs = NULL; + if (!noaddr) + paddrs = &addrs; } /* - * If tickets are address-less, forward address-less tickets. + * If tickets have addresses, get the address of the remote host. */ - if (paddrs) { - ret = _krb5_get_krbtgt (context, - ccache, - realm, - &ticket); - if(ret == 0) { - if (ticket->addresses.len == 0) - paddrs = NULL; - krb5_free_creds (context, ticket); - } - } - if (paddrs != NULL) { ret = getaddrinfo (hostname, NULL, NULL, &ai); @@ -233,9 +260,8 @@ krb5_get_forwarded_creds (krb5_context context, in_creds, &out_creds); krb5_free_addresses (context, &addrs); - if (ret) { + if (ret) return ret; - } memset (&cred, 0, sizeof(cred)); cred.pvno = 5; @@ -373,6 +399,14 @@ krb5_get_forwarded_creds (krb5_context context, if(buf_size != len) krb5_abortx(context, "internal error in ASN.1 encoder"); + /** + * Some older of the MIT gssapi library used clear-text tickets + * (warped inside AP-REQ encryption), use the krb5_auth_context + * flag KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED to support those + * tickets. The session key is used otherwise to encrypt the + * forwarded ticket. + */ + if (auth_context->flags & KRB5_AUTH_CONTEXT_CLEAR_FORWARDED_CRED) { cred.enc_part.etype = ENCTYPE_NULL; cred.enc_part.kvno = NULL; diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index ec106bb7ec..a9ed3857d0 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -145,7 +145,7 @@ _krb5_extract_ticket(krb5_context context, flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; - ret = _krb5_principalname2krb5_principal (context, + ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.cname, rep->kdc_rep.crealm); diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c index bd250cef2b..a59c903bd9 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 21712 2007-07-27 14:23:41Z lha $"); +RCSID("$Id: init_creds.c 21711 2007-07-27 14:22:02Z lha $"); void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 0043b5ef3c..441adff8fd 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: init_creds_pw.c 21428 2007-07-10 12:31:58Z lha $"); +RCSID("$Id: init_creds_pw.c 21931 2007-08-27 14:11:55Z lha $"); typedef struct krb5_get_init_creds_ctx { KDCOptions flags; @@ -1547,9 +1547,15 @@ krb5_get_init_creds_password(krb5_context context, char buf[BUFSIZ]; krb5_error_code ret; - if (in_options == NULL) + if (in_options == NULL) { + const char *realm = krb5_principal_get_realm(context, client); ret = krb5_get_init_creds_opt_alloc(context, &options); - else + if (ret == 0) + krb5_get_init_creds_opt_set_default_flags(context, + NULL, + realm, + options); + } else ret = _krb5_get_init_creds_opt_copy(context, in_options, &options); if (ret) return ret; diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index c945a9ce13..8afaa6ea80 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -43,7 +43,7 @@ #include "kcm.h" -RCSID("$Id: kcm.c 17442 2006-05-05 09:31:15Z lha $"); +RCSID("$Id: kcm.c 22108 2007-12-03 17:23:53Z lha $"); typedef struct krb5_kcmcache { char *name; @@ -829,6 +829,27 @@ kcm_get_version(krb5_context context, return 0; } +static krb5_error_code +kcm_move(krb5_context context, krb5_ccache from, krb5_ccache to) +{ + krb5_set_error_string(context, "kcm_move not implemented"); + return EINVAL; +} + +static krb5_error_code +kcm_default_name(krb5_context context, char **str) +{ + return _krb5_expand_default_cc_name(context, + KRB5_DEFAULT_CCNAME_KCM, + str); +} + +/** + * Variable containing the KCM based credential cache implemention. + * + * @ingroup krb5_ccache + */ + const krb5_cc_ops krb5_kcm_ops = { "KCM", kcm_get_name, @@ -845,7 +866,12 @@ const krb5_cc_ops krb5_kcm_ops = { kcm_end_get, kcm_remove_cred, kcm_set_flags, - kcm_get_version + kcm_get_version, + NULL, + NULL, + NULL, + kcm_move, + kcm_default_name }; krb5_boolean diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index f6c7858c12..79a3f20e79 100644 --- a/source4/heimdal/lib/krb5/keytab.c +++ b/source4/heimdal/lib/krb5/keytab.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab.c 20211 2007-02-09 07:11:03Z lha $"); +RCSID("$Id: keytab.c 22532 2008-01-27 11:59:18Z lha $"); /* * Register a new keytab in `ops' @@ -337,8 +337,9 @@ krb5_kt_get_entry(krb5_context context, ret = krb5_kt_start_seq_get (context, id, &cursor); if (ret) { - krb5_clear_error_string(context); - return KRB5_KT_NOTFOUND; /* XXX i.e. file not found */ + /* This is needed for krb5_verify_init_creds, but keep error + * string from previous error for the human. */ + return KRB5_KT_NOTFOUND; } entry->vno = 0; diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index 4ada3a463e..be195d96c2 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_file.c 17457 2006-05-05 12:36:57Z lha $"); +RCSID("$Id: keytab_file.c 22532 2008-01-27 11:59:18Z lha $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 @@ -334,8 +334,8 @@ fkt_start_seq_get_int(krb5_context context, c->fd = open (d->filename, flags); if (c->fd < 0) { ret = errno; - krb5_set_error_string(context, "%s: %s", d->filename, - strerror(ret)); + krb5_set_error_string(context, "keytab %s open failed: %s", + d->filename, strerror(ret)); return ret; } ret = _krb5_xlock(context, c->fd, exclusive, d->filename); diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c index 77455ba5f7..aa612add09 100644 --- a/source4/heimdal/lib/krb5/keytab_keyfile.c +++ b/source4/heimdal/lib/krb5/keytab_keyfile.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_keyfile.c 20695 2007-05-30 14:09:09Z lha $"); +RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $"); /* afs keyfile operations --------------------------------------- */ @@ -197,8 +197,8 @@ akf_start_seq_get(krb5_context context, c->fd = open (d->filename, O_RDONLY|O_BINARY, 0600); if (c->fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_string(context, "keytab afs keyfil open %s failed: %s", + d->filename, strerror(ret)); return ret; } diff --git a/source4/heimdal/lib/krb5/keytab_krb4.c b/source4/heimdal/lib/krb5/keytab_krb4.c index 907836c144..32bb00141a 100644 --- a/source4/heimdal/lib/krb5/keytab_krb4.c +++ b/source4/heimdal/lib/krb5/keytab_krb4.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_krb4.c 17046 2006-04-10 17:10:53Z lha $"); +RCSID("$Id: keytab_krb4.c 22532 2008-01-27 11:59:18Z lha $"); struct krb4_kt_data { char *filename; @@ -134,14 +134,15 @@ krb4_kt_start_seq_get_int (krb5_context context, if (c->fd < 0) { ret = errno; free (ed); - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_string(context, "keytab krb5 open %s failed: %s", + d->filename, strerror(ret)); return ret; } c->sp = krb5_storage_from_fd(c->fd); if(c->sp == NULL) { close(c->fd); free(ed); + krb5_set_error_string(context, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_eof_code(c->sp, KRB5_KT_END); @@ -369,8 +370,11 @@ krb4_kt_remove_entry(krb5_context context, if(fd < 0) { memset(data.data, 0, data.length); krb5_data_free(&data); - if(errno == EACCES || errno == EROFS) + if(errno == EACCES || errno == EROFS) { + krb5_set_error_string(context, "failed to open %s for writing", + d->filename); return KRB5_KT_NOWRITE; + } return errno; } @@ -378,14 +382,16 @@ krb4_kt_remove_entry(krb5_context context, memset(data.data, 0, data.length); krb5_data_free(&data); close(fd); - krb5_set_error_string(context, "failed writing to \"%s\"", d->filename); + krb5_set_error_string(context, "failed writing to file %s", + d->filename); return errno; } memset(data.data, 0, data.length); if(fstat(fd, &st) < 0) { krb5_data_free(&data); close(fd); - krb5_set_error_string(context, "failed getting size of \"%s\"", d->filename); + krb5_set_error_string(context, "failed getting size of file %s", + d->filename); return errno; } st.st_size -= data.length; @@ -396,7 +402,8 @@ krb4_kt_remove_entry(krb5_context context, if(n <= 0) { krb5_data_free(&data); close(fd); - krb5_set_error_string(context, "failed writing to \"%s\"", d->filename); + krb5_set_error_string(context, "failed writing to file %s", + d->filename); return errno; } @@ -405,17 +412,20 @@ krb4_kt_remove_entry(krb5_context context, if(ftruncate(fd, data.length) < 0) { krb5_data_free(&data); close(fd); - krb5_set_error_string(context, "failed truncating \"%s\"", d->filename); + krb5_set_error_string(context, "failed truncating file %s", + d->filename); return errno; } krb5_data_free(&data); if(close(fd) < 0) { - krb5_set_error_string(context, "error closing \"%s\"", d->filename); + krb5_set_error_string(context, "error closing %s", + d->filename); return errno; } return 0; } else { krb5_storage_free(sp); + krb5_set_error_string(context, "Keytab entry not found"); return KRB5_KT_NOTFOUND; } } diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index 9a84dde61a..7e04446fe0 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -276,7 +276,7 @@ _krb5_mk_req_internal ( krb5_key_usage /*checksum_usage*/, krb5_key_usage /*encrypt_usage*/); -void KRB5_LIB_FUNCTION +krb5_error_code KRB5_LIB_FUNCTION _krb5_n_fold ( const void */*str*/, size_t /*len*/, @@ -292,7 +292,7 @@ _krb5_oid_to_enctype ( krb5_error_code _krb5_pac_sign ( krb5_context /*context*/, - struct krb5_pac */*p*/, + krb5_pac /*p*/, time_t /*authtime*/, krb5_principal /*principal*/, const krb5_keyblock */*server_key*/, @@ -396,13 +396,6 @@ _krb5_plugin_get_next (struct krb5_plugin */*p*/); void * _krb5_plugin_get_symbol (struct krb5_plugin */*p*/); -krb5_error_code -_krb5_plugin_register ( - krb5_context /*context*/, - enum krb5_plugin_type /*type*/, - const char */*name*/, - void */*symbol*/); - krb5_error_code KRB5_LIB_FUNCTION _krb5_principal2principalname ( PrincipalName */*p*/, diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 740b394be8..647d8886b7 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -670,6 +670,12 @@ krb5_cc_initialize ( krb5_ccache /*id*/, krb5_principal /*primary_principal*/); +krb5_error_code +krb5_cc_move ( + krb5_context /*context*/, + krb5_ccache /*from*/, + krb5_ccache /*to*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_cc_new_unique ( krb5_context /*context*/, @@ -1329,6 +1335,13 @@ krb5_digest_init_request ( krb5_realm /*realm*/, krb5_ccache /*ccache*/); +krb5_error_code +krb5_digest_probe ( + krb5_context /*context*/, + krb5_realm /*realm*/, + krb5_ccache /*ccache*/, + unsigned */*flags*/); + krb5_boolean krb5_digest_rep_get_status ( krb5_context /*context*/, @@ -1606,6 +1619,9 @@ krb5_err ( ...) __attribute__ ((noreturn, format (printf, 4, 5))); +krb5_error_code KRB5_LIB_FUNCTION + __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c); + krb5_error_code KRB5_LIB_FUNCTION krb5_error_from_rd_error ( krb5_context /*context*/, @@ -1694,11 +1710,6 @@ krb5_free_creds ( krb5_context /*context*/, krb5_creds */*c*/); -krb5_error_code KRB5_LIB_FUNCTION -krb5_free_creds_contents ( - krb5_context /*context*/, - krb5_creds */*c*/); - void KRB5_LIB_FUNCTION krb5_free_data ( krb5_context /*context*/, @@ -2243,6 +2254,14 @@ krb5_get_pw_salt ( krb5_const_principal /*principal*/, krb5_salt */*salt*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_get_renewed_creds ( + krb5_context /*context*/, + krb5_creds */*creds*/, + krb5_const_principal /*client*/, + krb5_ccache /*ccache*/, + const char */*in_tkt_service*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_get_server_rcache ( krb5_context /*context*/, @@ -2797,45 +2816,45 @@ krb5_openlog ( krb5_error_code krb5_pac_add_buffer ( krb5_context /*context*/, - struct krb5_pac */*p*/, + krb5_pac /*p*/, uint32_t /*type*/, const krb5_data */*data*/); void krb5_pac_free ( krb5_context /*context*/, - struct krb5_pac */*pac*/); + krb5_pac /*pac*/); krb5_error_code krb5_pac_get_buffer ( krb5_context /*context*/, - struct krb5_pac */*p*/, + krb5_pac /*p*/, uint32_t /*type*/, krb5_data */*data*/); krb5_error_code krb5_pac_get_types ( krb5_context /*context*/, - struct krb5_pac */*p*/, + krb5_pac /*p*/, size_t */*len*/, uint32_t **/*types*/); krb5_error_code krb5_pac_init ( krb5_context /*context*/, - struct krb5_pac **/*pac*/); + krb5_pac */*pac*/); krb5_error_code krb5_pac_parse ( krb5_context /*context*/, const void */*ptr*/, size_t /*len*/, - struct krb5_pac **/*pac*/); + krb5_pac */*pac*/); krb5_error_code krb5_pac_verify ( krb5_context /*context*/, - const struct krb5_pac */*pac*/, + const krb5_pac /*pac*/, time_t /*authtime*/, krb5_const_principal /*principal*/, const krb5_keyblock */*server*/, @@ -2887,6 +2906,13 @@ krb5_password_key_proc ( krb5_const_pointer /*keyseed*/, krb5_keyblock **/*key*/); +krb5_error_code +krb5_plugin_register ( + krb5_context /*context*/, + enum krb5_plugin_type /*type*/, + const char */*name*/, + void */*symbol*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_prepend_config_files ( const char */*filelist*/, diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 4f9a63bf05..571eb6192a 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h 21551 2007-07-15 09:03:39Z lha $ */ +/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -75,15 +75,16 @@ 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; -struct krb5_ntlm; -typedef struct krb5_ntlm *krb5_ntlm; +struct krb5_digest_data; +typedef struct krb5_digest_data *krb5_digest; +struct krb5_ntlm_data; +typedef struct krb5_ntlm_data *krb5_ntlm; -typedef struct krb5_pac *krb5_pac; +struct krb5_pac_data; +typedef struct krb5_pac_data *krb5_pac; -typedef struct krb5_rd_req_in_ctx *krb5_rd_req_in_ctx; -typedef struct krb5_rd_req_out_ctx *krb5_rd_req_out_ctx; +typedef struct krb5_rd_req_in_ctx_data *krb5_rd_req_in_ctx; +typedef struct krb5_rd_req_out_ctx_data *krb5_rd_req_out_ctx; typedef CKSUMTYPE krb5_cksumtype; @@ -417,6 +418,8 @@ typedef struct krb5_cc_ops { krb5_error_code (*get_cache_first)(krb5_context, krb5_cc_cursor *); krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *); krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor); + krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache); + krb5_error_code (*default_name)(krb5_context, char **); } krb5_cc_ops; struct krb5_log_facility; @@ -753,7 +756,7 @@ enum { KRB5_PRINCIPAL_UNPARSE_DISPLAY = 4 }; -typedef struct krb5_sendto_ctx *krb5_sendto_ctx; +typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx; #define KRB5_SENDTO_DONE 0 #define KRB5_SENDTO_RESTART 1 diff --git a/source4/heimdal/lib/krb5/krb5_ccapi.h b/source4/heimdal/lib/krb5/krb5_ccapi.h index b53d77ef18..59a38425c2 100644 --- a/source4/heimdal/lib/krb5/krb5_ccapi.h +++ b/source4/heimdal/lib/krb5/krb5_ccapi.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_ccapi.h 17442 2006-05-05 09:31:15Z lha $ */ +/* $Id: krb5_ccapi.h 22090 2007-12-02 23:23:43Z lha $ */ #ifndef KRB5_CCAPI_H #define KRB5_CCAPI_H 1 @@ -180,18 +180,18 @@ typedef struct cc_ccache_functions { cc_int32 (*destroy)(cc_ccache_t); cc_int32 (*set_default)(cc_ccache_t); cc_int32 (*get_credentials_version)(cc_ccache_t, cc_uint32*); - cc_int32 (*get_name)(cc_ccache_t ccache,cc_string_t*); + cc_int32 (*get_name)(cc_ccache_t, cc_string_t*); cc_int32 (*get_principal)(cc_ccache_t, cc_uint32, cc_string_t*); cc_int32 (*set_principal)(cc_ccache_t, cc_uint32, const char*); cc_int32 (*store_credentials)(cc_ccache_t, const cc_credentials_union*); cc_int32 (*remove_credentials)(cc_ccache_t, cc_credentials_t); cc_int32 (*new_credentials_iterator)(cc_ccache_t, cc_credentials_iterator_t*); - cc_int32 (*move)(cc_ccache_t source, cc_ccache_t); + cc_int32 (*move)(cc_ccache_t, cc_ccache_t); cc_int32 (*lock)(cc_ccache_t, cc_uint32, cc_uint32); cc_int32 (*unlock)(cc_ccache_t); cc_int32 (*get_last_default_time)(cc_ccache_t, cc_time_t*); - cc_int32 (*get_change_time)(cc_ccache_t ccache, cc_time_t*); + cc_int32 (*get_change_time)(cc_ccache_t, cc_time_t*); cc_int32 (*compare)(cc_ccache_t, cc_ccache_t, cc_uint32*); cc_int32 (*get_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t *); cc_int32 (*set_kdc_time_offset)(cc_ccache_t, cc_int32, cc_time_t); diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index b41e6e1182..8b7c41cc80 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5_locl.h 21552 2007-07-15 09:04:00Z lha $ */ +/* $Id: krb5_locl.h 22226 2007-12-08 21:31:53Z lha $ */ #ifndef __KRB5_LOCL_H__ #define __KRB5_LOCL_H__ @@ -231,14 +231,18 @@ typedef struct krb5_context_data { krb5_addresses *ignore_addresses; char *default_cc_name; char *default_cc_name_env; + int default_cc_name_set; void *mutex; /* protects error_string/error_buf */ int large_msg_size; - int dns_canonicalize_hostname; + int flags; +#define KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME 1 +#define KRB5_CTX_F_CHECK_PAC 2 struct send_to_kdc *send_to_kdc; } krb5_context_data; #define KRB5_DEFAULT_CCNAME_FILE "FILE:/tmp/krb5cc_%{uid}" #define KRB5_DEFAULT_CCNAME_API "API:" +#define KRB5_DEFAULT_CCNAME_KCM "KCM:%{uid}" #define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH 1 #define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH 2 @@ -248,11 +252,11 @@ typedef struct krb5_context_data { * Configurable options */ -#ifndef KRB5_DEFAULT_CCNAME +#ifndef KRB5_DEFAULT_CCTYPE #ifdef __APPLE__ -#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_API +#define KRB5_DEFAULT_CCTYPE (&krb5_acc_ops) #else -#define KRB5_DEFAULT_CCNAME KRB5_DEFAULT_CCNAME_FILE +#define KRB5_DEFAULT_CCTYPE (&krb5_fcc_ops) #endif #endif diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c index ff9261a7db..01bcb09d3b 100644 --- a/source4/heimdal/lib/krb5/mcache.c +++ b/source4/heimdal/lib/krb5/mcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: mcache.c 19834 2007-01-11 09:26:21Z lha $"); +RCSID("$Id: mcache.c 22107 2007-12-03 17:22:51Z lha $"); typedef struct krb5_mcache { char *name; @@ -401,6 +401,57 @@ mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } +static krb5_error_code +mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) +{ + krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to); + struct link *creds; + krb5_principal principal; + krb5_mcache **n; + + HEIMDAL_MUTEX_lock(&mcc_mutex); + + /* drop the from cache from the linked list to avoid lookups */ + for(n = &mcc_head; n && *n; n = &(*n)->next) { + if(mfrom == *n) { + *n = mfrom->next; + break; + } + } + + /* swap creds */ + creds = mto->creds; + mto->creds = mfrom->creds; + mfrom->creds = creds; + /* swap principal */ + principal = mto->primary_principal; + mto->primary_principal = mfrom->primary_principal; + mfrom->primary_principal = principal; + + HEIMDAL_MUTEX_unlock(&mcc_mutex); + mcc_destroy(context, from); + + return 0; +} + +static krb5_error_code +mcc_default_name(krb5_context context, char **str) +{ + *str = strdup("MEMORY:"); + if (*str == NULL) { + krb5_set_error_string(context, "out of memory"); + return ENOMEM; + } + return 0; +} + + +/** + * Variable containing the MEMORY based credential cache implemention. + * + * @ingroup krb5_ccache + */ + const krb5_cc_ops krb5_mcc_ops = { "MEMORY", mcc_get_name, @@ -420,5 +471,7 @@ const krb5_cc_ops krb5_mcc_ops = { NULL, mcc_get_cache_first, mcc_get_cache_next, - mcc_end_cache_get + mcc_end_cache_get, + mcc_move, + mcc_default_name }; diff --git a/source4/heimdal/lib/krb5/n-fold.c b/source4/heimdal/lib/krb5/n-fold.c index 1474a76b77..53528cfd1f 100644 --- a/source4/heimdal/lib/krb5/n-fold.c +++ b/source4/heimdal/lib/krb5/n-fold.c @@ -32,21 +32,23 @@ #include "krb5_locl.h" -RCSID("$Id: n-fold.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $"); -static void +static krb5_error_code rr13(unsigned char *buf, size_t len) { unsigned char *tmp; int bytes = (len + 7) / 8; int i; if(len == 0) - return; + return 0; { const int bits = 13 % len; const int lbit = len % 8; tmp = malloc(bytes); + if (tmp == NULL) + return ENOMEM; memcpy(tmp, buf, bytes); if(lbit) { /* pad final byte with inital bits */ @@ -75,9 +77,10 @@ rr13(unsigned char *buf, size_t len) } free(tmp); } + return 0; } -/* Add `b' to `a', both beeing one's complement numbers. */ +/* Add `b' to `a', both being one's complement numbers. */ static void add1(unsigned char *a, unsigned char *b, size_t len) { @@ -95,22 +98,28 @@ add1(unsigned char *a, unsigned char *b, size_t len) } } -void KRB5_LIB_FUNCTION +krb5_error_code KRB5_LIB_FUNCTION _krb5_n_fold(const void *str, size_t len, void *key, size_t size) { /* if len < size we need at most N * len bytes, ie < 2 * size; if len > size we need at most 2 * len */ + krb5_error_code ret = 0; size_t maxlen = 2 * max(size, len); size_t l = 0; unsigned char *tmp = malloc(maxlen); unsigned char *buf = malloc(len); + if (tmp == NULL || buf == NULL) + return ENOMEM; + memcpy(buf, str, len); memset(key, 0, size); do { memcpy(tmp + l, buf, len); l += len; - rr13(buf, len * 8); + ret = rr13(buf, len * 8); + if (ret) + goto out; while(l >= size) { add1(key, tmp, size); l -= size; @@ -119,8 +128,10 @@ _krb5_n_fold(const void *str, size_t len, void *key, size_t size) memmove(tmp, tmp + size, l); } } while(l != 0); +out: memset(buf, 0, len); free(buf); memset(tmp, 0, maxlen); free(tmp); + return ret; } diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c index f7a5e83ea3..0b44ca1da3 100644 --- a/source4/heimdal/lib/krb5/pac.c +++ b/source4/heimdal/lib/krb5/pac.c @@ -32,8 +32,9 @@ */ #include "krb5_locl.h" +#include -RCSID("$Id: pac.c 21149 2007-06-18 21:50:22Z lha $"); +RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $"); struct PAC_INFO_BUFFER { uint32_t type; @@ -48,7 +49,7 @@ struct PACTYPE { struct PAC_INFO_BUFFER buffers[1]; }; -struct krb5_pac { +struct krb5_pac_data { struct PACTYPE *pac; krb5_data data; struct PAC_INFO_BUFFER *server_checksum; @@ -82,10 +83,10 @@ static const char zeros[PAC_ALIGNMENT] = { 0 }; krb5_error_code krb5_pac_parse(krb5_context context, const void *ptr, size_t len, - struct krb5_pac **pac) + krb5_pac *pac) { krb5_error_code ret; - struct krb5_pac *p; + krb5_pac p; krb5_storage *sp = NULL; uint32_t i, tmp, tmp2, header_end; @@ -216,10 +217,10 @@ out: } krb5_error_code -krb5_pac_init(krb5_context context, struct krb5_pac **pac) +krb5_pac_init(krb5_context context, krb5_pac *pac) { krb5_error_code ret; - struct krb5_pac *p; + krb5_pac p; p = calloc(1, sizeof(*p)); if (p == NULL) { @@ -248,7 +249,7 @@ krb5_pac_init(krb5_context context, struct krb5_pac **pac) } krb5_error_code -krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p, +krb5_pac_add_buffer(krb5_context context, krb5_pac p, uint32_t type, const krb5_data *data) { krb5_error_code ret; @@ -316,7 +317,7 @@ krb5_pac_add_buffer(krb5_context context, struct krb5_pac *p, } krb5_error_code -krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p, +krb5_pac_get_buffer(krb5_context context, krb5_pac p, uint32_t type, krb5_data *data) { krb5_error_code ret; @@ -361,7 +362,7 @@ krb5_pac_get_buffer(krb5_context context, struct krb5_pac *p, krb5_error_code krb5_pac_get_types(krb5_context context, - struct krb5_pac *p, + krb5_pac p, size_t *len, uint32_t **types) { @@ -385,7 +386,7 @@ krb5_pac_get_types(krb5_context context, */ void -krb5_pac_free(krb5_context context, struct krb5_pac *pac) +krb5_pac_free(krb5_context context, krb5_pac pac) { krb5_data_free(&pac->data); free(pac->pac); @@ -564,51 +565,48 @@ verify_logonname(krb5_context context, ret = krb5_storage_read(sp, s, len); if (ret != len) { krb5_storage_free(sp); - krb5_set_error_string(context, "Failed to read pac logon name"); + krb5_set_error_string(context, "Failed to read PAC logon name"); return EINVAL; } krb5_storage_free(sp); -#if 1 /* cheat for now */ - { - size_t i; - - if (len & 1) { - krb5_set_error_string(context, "PAC logon name malformed"); - return EINVAL; - } - - for (i = 0; i < len / 2; i++) { - if (s[(i * 2) + 1]) { - krb5_set_error_string(context, "PAC logon name not ASCII"); - return EINVAL; - } - s[i] = s[i * 2]; - } - s[i] = '\0'; - } -#else { + size_t ucs2len = len / 2; uint16_t *ucs2; - ssize_t ucs2len; size_t u8len; + unsigned int flags = WIND_RW_LE; - ucs2 = malloc(sizeof(ucs2[0]) * len / 2); - if (ucs2) - abort(); - ucs2len = wind_ucs2read(s, len / 2, ucs2); + ucs2 = malloc(sizeof(ucs2[0]) * ucs2len); + if (ucs2 == NULL) { + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len); free(s); - if (len < 0) - return -1; - ret = wind_ucs2toutf8(ucs2, ucs2len, NULL, &u8len); - if (ret < 0) - abort(); - s = malloc(u8len + 1); - if (s == NULL) - abort(); - wind_ucs2toutf8(ucs2, ucs2len, s, &u8len); + if (ret) { + free(ucs2); + krb5_set_error_string(context, "Failed to convert string to UCS-2"); + return ret; + } + ret = wind_ucs2utf8_length(ucs2, ucs2len, &u8len); + if (ret) { + free(ucs2); + krb5_set_error_string(context, "Failed to count length of UCS-2 string"); + return ret; + } + u8len += 1; /* Add space for NUL */ + s = malloc(u8len); + if (s == NULL) { + free(ucs2); + krb5_set_error_string(context, "malloc: out of memory"); + return ENOMEM; + } + ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len); free(ucs2); + if (ret) { + krb5_set_error_string(context, "Failed to convert to UTF-8"); + return ret; + } } -#endif ret = krb5_parse_name_flags(context, s, KRB5_PRINCIPAL_PARSE_NO_REALM, &p2); free(s); if (ret) @@ -703,7 +701,7 @@ out: krb5_error_code krb5_pac_verify(krb5_context context, - const struct krb5_pac *pac, + const krb5_pac pac, time_t authtime, krb5_const_principal principal, const krb5_keyblock *server, @@ -840,7 +838,7 @@ pac_checksum(krb5_context context, krb5_error_code _krb5_pac_sign(krb5_context context, - struct krb5_pac *p, + krb5_pac p, time_t authtime, krb5_principal principal, const krb5_keyblock *server_key, diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index c8587770f4..4a585bff07 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 21684 2007-07-23 23:09:10Z lha $"); +RCSID("$Id: pkinit.c 22673 2008-03-10 15:00:05Z lha $"); struct krb5_dh_moduli { char *name; @@ -139,17 +139,59 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f) return bn; } +struct certfind { + const char *type; + const heim_oid *oid; +}; + +/* + * Try searchin the key by to use by first looking for for PK-INIT + * EKU, then the Microsoft smart card EKU and last, no special EKU at all. + */ static krb5_error_code -_krb5_pk_create_sign(krb5_context context, - const heim_oid *eContentType, - krb5_data *eContent, - struct krb5_pk_identity *id, - hx509_peer_info peer, - krb5_data *sd_data) +find_cert(krb5_context context, struct krb5_pk_identity *id, + hx509_query *q, hx509_cert *cert) { - hx509_cert cert; - hx509_query *q; + struct certfind cf[3] = { + { "PKINIT EKU" }, + { "MS EKU" }, + { "no" } + }; + int i, ret; + + cf[0].oid = oid_id_pkekuoid(); + cf[1].oid = oid_id_pkinit_ms_eku(); + cf[2].oid = NULL; + + for (i = 0; i < sizeof(cf)/sizeof(cf[0]); i++) { + ret = hx509_query_match_eku(q, cf[i].oid); + if (ret) { + _krb5_pk_copy_error(context, id->hx509ctx, ret, + "Failed setting %s OID", cf[i].type); + return ret; + } + + ret = hx509_certs_find(id->hx509ctx, id->certs, q, cert); + if (ret == 0) + break; + _krb5_pk_copy_error(context, id->hx509ctx, ret, + "Failed cert for finding %s OID", cf[i].type); + } + return ret; +} + + +static krb5_error_code +create_signature(krb5_context context, + const heim_oid *eContentType, + krb5_data *eContent, + struct krb5_pk_identity *id, + hx509_peer_info peer, + krb5_data *sd_data) +{ + hx509_cert cert = NULL; + hx509_query *q = NULL; int ret; ret = hx509_query_alloc(id->hx509ctx, &q); @@ -162,13 +204,10 @@ _krb5_pk_create_sign(krb5_context context, hx509_query_match_option(q, HX509_QUERY_OPTION_PRIVATE_KEY); hx509_query_match_option(q, HX509_QUERY_OPTION_KU_DIGITALSIGNATURE); - ret = hx509_certs_find(id->hx509ctx, id->certs, q, &cert); + ret = find_cert(context, id, q, &cert); hx509_query_free(id->hx509ctx, q); - if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Find certificate to signed CMS data"); + if (ret) return ret; - } ret = hx509_cms_create_signed_1(id->hx509ctx, 0, @@ -181,11 +220,14 @@ _krb5_pk_create_sign(krb5_context context, NULL, id->certs, sd_data); - if (ret) - _krb5_pk_copy_error(context, id->hx509ctx, ret, "create CMS signedData"); hx509_cert_free(cert); + if (ret) { + _krb5_pk_copy_error(context, id->hx509ctx, ret, + "Create CMS signedData"); + return ret; + } - return ret; + return 0; } static int @@ -212,8 +254,7 @@ cert2epi(hx509_context context, void *ctx, hx509_cert c) return ENOMEM; } - ret = hx509_name_to_der_name(subject, &id.subjectName->data, - &id.subjectName->length); + ret = hx509_name_binary(subject, id.subjectName); if (ret) { hx509_name_free(&subject); free_ExternalPrincipalIdentifier(&id); @@ -544,12 +585,8 @@ pk_mk_padata(krb5_context context, } else krb5_abortx(context, "internal pkinit error"); - ret = _krb5_pk_create_sign(context, - oid, - &buf, - ctx->id, - ctx->peer, - &sd_buf); + ret = create_signature(context, oid, &buf, ctx->id, + ctx->peer, &sd_buf); krb5_data_free(&buf); if (ret) goto out; @@ -878,7 +915,8 @@ pk_verify_host(krb5_context context, hx509_octet_string_list list; int i; - ret = hx509_cert_find_subjectAltName_otherName(host->cert, + ret = hx509_cert_find_subjectAltName_otherName(ctx->id->hx509ctx, + host->cert, oid_id_pkinit_san(), &list); if (ret) { diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index 43fa3f5b45..bae28496aa 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: plugin.c 21702 2007-07-26 19:13:53Z lha $"); +RCSID("$Id: plugin.c 22033 2007-11-10 10:39:47Z lha $"); #ifdef HAVE_DLFCN_H #include #endif @@ -117,11 +117,23 @@ loadlib(krb5_context context, } #endif /* HAVE_DLOPEN */ +/** + * Register a plugin symbol name of specific type. + * @param context a Keberos context + * @param type type of plugin symbol + * @param name name of plugin symbol + * @param symbol a pointer to the named symbol + * @return In case of error a non zero error com_err error is returned + * and the Kerberos error string is set. + * + * @ingroup krb5_support + */ + krb5_error_code -_krb5_plugin_register(krb5_context context, - enum krb5_plugin_type type, - const char *name, - void *symbol) +krb5_plugin_register(krb5_context context, + enum krb5_plugin_type type, + const char *name, + void *symbol) { struct plugin *e; @@ -250,4 +262,3 @@ _krb5_plugin_free(struct krb5_plugin *list) list = next; } } - diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index c1a29d266b..cdad477115 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997-2006 Kungliga Tekniska Högskolan + * Copyright (c) 1997-2007 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -31,6 +31,22 @@ * SUCH DAMAGE. */ +/** + * @page page_principal The principal handing functions. + * + * A Kerberos principal is a email address looking string that + * contains to parts separeted by a @. The later part is the kerbero + * realm the principal belongs to and the former is a list of 0 or + * more components. For example + * @verbatim +lha@SU.SE +host/hummel.it.su.se@SU.SE +host/admin@H5L.ORG +@endverbatim + * + * See the library functions here: @ref krb5_principal + */ + #include "krb5_locl.h" #ifdef HAVE_RES_SEARCH #define USE_RESOLVER @@ -41,7 +57,7 @@ #include #include "resolve.h" -RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $"); +RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -49,6 +65,21 @@ RCSID("$Id: principal.c 21285 2007-06-25 12:30:55Z lha $"); #define princ_ncomp(P, N) ((P)->name.name_string.val[(N)]) #define princ_realm(P) ((P)->realm) +/** + * Frees a Kerberos principal allocated by the library with + * krb5_parse_name(), krb5_make_principal() or any other related + * principal functions. + * + * @param context A Kerberos context. + * @param p a principal to free. + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + + + void KRB5_LIB_FUNCTION krb5_free_principal(krb5_context context, krb5_principal p) @@ -804,7 +835,7 @@ krb5_425_conv_principal_ext2(krb5_context context, char local_hostname[MAXHOSTNAMELEN]; /* do the following: if the name is found in the - `v4_name_convert:host' part, is is assumed to be a `host' type + `v4_name_convert:host' part, is assumed to be a `host' type principal, and the instance is looked up in the `v4_instance_convert' part. if not found there the name is (optionally) looked up as a hostname, and if that doesn't yield diff --git a/source4/heimdal/lib/krb5/rd_priv.c b/source4/heimdal/lib/krb5/rd_priv.c index 47b5df85b2..ed7a2ccc52 100644 --- a/source4/heimdal/lib/krb5/rd_priv.c +++ b/source4/heimdal/lib/krb5/rd_priv.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: rd_priv.c 21770 2007-08-01 04:04:33Z lha $"); +RCSID("$Id: rd_priv.c 21751 2007-07-31 20:42:20Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_priv(krb5_context context, diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 001b47f094..0f33b97164 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -33,7 +33,7 @@ #include -RCSID("$Id: rd_req.c 21004 2007-06-08 01:53:10Z lha $"); +RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $"); static krb5_error_code decrypt_tkt_enc_part (krb5_context context, @@ -137,7 +137,7 @@ check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc) krb5_error_code ret; /* - * Windows 2000 and 2003 uses this inside their TGT so its normaly + * Windows 2000 and 2003 uses this inside their TGT so it's normaly * not seen by others, however, samba4 joined with a Windows AD as * a Domain Controller gets exposed to this. */ @@ -512,13 +512,13 @@ krb5_verify_ap_req2(krb5_context context, * */ -struct krb5_rd_req_in_ctx { +struct krb5_rd_req_in_ctx_data { krb5_keytab keytab; krb5_keyblock *keyblock; - krb5_boolean no_pac_check; + krb5_boolean check_pac; }; -struct krb5_rd_req_out_ctx { +struct krb5_rd_req_out_ctx_data { krb5_keyblock *keyblock; krb5_flags ap_req_options; krb5_ticket *ticket; @@ -536,6 +536,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx) krb5_set_error_string(context, "out of memory"); return ENOMEM; } + (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0; return 0; } @@ -548,12 +549,24 @@ krb5_rd_req_in_set_keytab(krb5_context context, return 0; } +/** + * Set if krb5_rq_red() is going to check the Windows PAC or not + * + * @param context Keberos 5 context. + * @param in krb5_rd_req_in_ctx to check the option on. + * @param flag flag to select if to check the pac (TRUE) or not (FALSE). + * + * @return Kerberos 5 error code, see krb5_get_error_message(). + * + * @ingroup krb5 + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_rd_req_in_set_pac_check(krb5_context context, krb5_rd_req_in_ctx in, krb5_boolean flag) { - in->no_pac_check = !flag; + in->check_pac = flag; return 0; } @@ -826,20 +839,21 @@ krb5_rd_req_ctx(krb5_context context, goto out; } - ret = krb5_verify_ap_req(context, - auth_context, - &ap_req, - server, - o->keyblock, - 0, - &o->ap_req_options, - &o->ticket); + ret = krb5_verify_ap_req2(context, + auth_context, + &ap_req, + server, + o->keyblock, + 0, + &o->ap_req_options, + &o->ticket, + KRB5_KU_AP_REQ_AUTH); if (ret) goto out; /* If there is a PAC, verify its server signature */ - if (inctx->no_pac_check == FALSE) { + if (inctx->check_pac) { krb5_pac pac; krb5_data data; diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index c1a4df2b01..2582a615c0 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: send_to_kdc.c 21062 2007-06-12 17:58:57Z lha $"); +RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $"); struct send_to_kdc { krb5_send_to_kdc_func func; @@ -448,7 +448,7 @@ krb5_set_send_to_kdc_func(krb5_context context, return 0; } -struct krb5_sendto_ctx { +struct krb5_sendto_ctx_data { int flags; int type; krb5_sendto_ctx_func func; diff --git a/source4/heimdal/lib/krb5/store.c b/source4/heimdal/lib/krb5/store.c index 4abcf44a43..c9cbbb5cef 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 20529 2007-04-22 14:28:19Z lha $"); +RCSID("$Id: store.c 22071 2007-11-14 20:04:50Z lha $"); #define BYTEORDER_IS(SP, V) (((SP)->flags & KRB5_STORAGE_BYTEORDER_MASK) == (V)) #define BYTEORDER_IS_LE(SP) BYTEORDER_IS((SP), KRB5_STORAGE_BYTEORDER_LE) @@ -838,8 +838,8 @@ krb5_ret_creds(krb5_storage *sp, krb5_creds *creds) if(ret) goto cleanup; /* * Runtime detect the what is the higher bits of the bitfield. If - * any of the higher bits are set in the input data, its either a - * new ticket flag (and this code need to be removed), or its a + * any of the higher bits are set in the input data, it's either a + * new ticket flag (and this code need to be removed), or it's a * MIT cache (or new Heimdal cache), lets change it to our current * format. */ @@ -993,8 +993,8 @@ krb5_ret_creds_tag(krb5_storage *sp, if(ret) goto cleanup; /* * Runtime detect the what is the higher bits of the bitfield. If - * any of the higher bits are set in the input data, its either a - * new ticket flag (and this code need to be removed), or its a + * any of the higher bits are set in the input data, it's either a + * new ticket flag (and this code need to be removed), or it's a * MIT cache (or new Heimdal cache), lets change it to our current * format. */ diff --git a/source4/heimdal/lib/krb5/store_emem.c b/source4/heimdal/lib/krb5/store_emem.c index 07acdd1a00..c38c1b53c3 100644 --- a/source4/heimdal/lib/krb5/store_emem.c +++ b/source4/heimdal/lib/krb5/store_emem.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include "store-int.h" -RCSID("$Id: store_emem.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: store_emem.c 22574 2008-02-05 20:31:55Z lha $"); typedef struct emem_storage{ unsigned char *base; @@ -115,13 +115,28 @@ emem_free(krb5_storage *sp) krb5_storage * KRB5_LIB_FUNCTION krb5_storage_emem(void) { - krb5_storage *sp = malloc(sizeof(krb5_storage)); - emem_storage *s = malloc(sizeof(*s)); + krb5_storage *sp; + emem_storage *s; + + sp = malloc(sizeof(krb5_storage)); + if (sp == NULL) + return NULL; + + s = malloc(sizeof(*s)); + if (s == NULL) { + free(sp); + return NULL; + } sp->data = s; sp->flags = 0; sp->eof_code = HEIM_ERR_EOF; s->size = 1024; s->base = malloc(s->size); + if (s->base == NULL) { + free(sp); + free(s); + return NULL; + } s->len = 0; s->ptr = s->base; sp->fetch = emem_fetch; diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c index 7f5498f592..9b67ecc04f 100644 --- a/source4/heimdal/lib/krb5/transited.c +++ b/source4/heimdal/lib/krb5/transited.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: transited.c 17043 2006-04-10 10:26:35Z lha $"); +RCSID("$Id: transited.c 21745 2007-07-31 16:11:25Z lha $"); /* this is an attempt at one of the most horrible `compression' schemes that has ever been invented; it's so amazingly brain-dead @@ -87,6 +87,10 @@ make_path(krb5_context context, struct tr_realm *r, if(strcmp(p, to) == 0) break; tmp = calloc(1, sizeof(*tmp)); + if(tmp == NULL){ + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } tmp->next = path; path = tmp; path->realm = strdup(p); @@ -107,6 +111,10 @@ make_path(krb5_context context, struct tr_realm *r, if(strncmp(to, from, p - from) == 0) break; tmp = calloc(1, sizeof(*tmp)); + if(tmp == NULL){ + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } tmp->next = path; path = tmp; path->realm = malloc(p - from + 1); @@ -277,6 +285,10 @@ decode_realms(krb5_context context, } if(tr[i] == ','){ tmp = malloc(tr + i - start + 1); + if(tmp == NULL){ + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); @@ -290,6 +302,11 @@ decode_realms(krb5_context context, } } tmp = malloc(tr + i - start + 1); + if(tmp == NULL){ + free(*realms); + krb5_set_error_string (context, "malloc: out of memory"); + return ENOMEM; + } memcpy(tmp, start, tr + i - start); tmp[tr + i - start] = '\0'; r = make_realm(tmp); diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c index 3f99df6391..37b1e35dd1 100644 --- a/source4/heimdal/lib/krb5/v4_glue.c +++ b/source4/heimdal/lib/krb5/v4_glue.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: v4_glue.c 21572 2007-07-16 05:13:08Z lha $"); +RCSID("$Id: v4_glue.c 22071 2007-11-14 20:04:50Z lha $"); #include "krb5-v4compat.h" @@ -599,7 +599,7 @@ _krb5_krb_cr_err_reply(krb5_context context, RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error); RCHECK(ret, put_nir(sp, name, inst, realm), error); RCHECK(ret, krb5_store_int32(sp, time_ws), error); - /* If its a Kerberos 4 error-code, remove the et BASE */ + /* If it is a Kerberos 4 error-code, remove the et BASE */ if (e >= ERROR_TABLE_BASE_krb && e <= ERROR_TABLE_BASE_krb + 255) e -= ERROR_TABLE_BASE_krb; RCHECK(ret, krb5_store_int32(sp, e), error); -- cgit