diff options
author | Stefan Metzmacher <metze@samba.org> | 2008-08-01 07:08:51 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2008-08-01 16:11:00 +0200 |
commit | a925f039ee382df0f3be434108416bab0d17e8c0 (patch) | |
tree | 6055ac5d6e81435bb5a8fa88959535e99c850a55 /source4/heimdal/lib/krb5 | |
parent | cf875a562173d5ae99080cea594e79c6a5555307 (diff) | |
download | samba-a925f039ee382df0f3be434108416bab0d17e8c0.tar.gz samba-a925f039ee382df0f3be434108416bab0d17e8c0.tar.bz2 samba-a925f039ee382df0f3be434108416bab0d17e8c0.zip |
heimdal: update to lorikeet-heimdal rev 801
metze
(This used to be commit d6c54a66fb23c784ef221a3c1cf766b72bdb5a0b)
Diffstat (limited to 'source4/heimdal/lib/krb5')
64 files changed, 2803 insertions, 1565 deletions
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 775239cf6d..8dd8687005 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -37,7 +37,7 @@ #include <dlfcn.h> #endif -RCSID("$Id: acache.c 22669 2008-03-09 23:39:25Z lha $"); +RCSID("$Id: acache.c 23316 2008-06-23 04:32:32Z lha $"); /* XXX should we fetch these for each open ? */ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; @@ -68,6 +68,7 @@ static const struct { { ccIteratorEnd, KRB5_CC_END }, { ccErrNoMem, KRB5_CC_NOMEM }, { ccErrServerUnavailable, KRB5_CC_NOSUPP }, + { ccErrInvalidCCache, KRB5_CC_BADNAME }, { ccNoError, 0 } }; @@ -114,15 +115,17 @@ init_ccapi(krb5_context context) cc_handle = dlopen(lib, RTLD_LAZY); if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "Failed to load %s", lib); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to load %s", lib); return KRB5_CC_NOSUPP; } init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { - krb5_set_error_string(context, "Failed to find cc_initialize" - "in %s: %s", lib, dlerror()); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Failed to find cc_initialize" + "in %s: %s", lib, dlerror()); dlclose(cc_handle); return KRB5_CC_NOSUPP; } @@ -130,7 +133,7 @@ init_ccapi(krb5_context context) return 0; #else HEIMDAL_MUTEX_unlock(&acc_mutex); - krb5_set_error_string(context, "no support for shared object"); + krb5_set_error_message(context, KRB5_CC_NOSUPP, "no support for shared object"); return KRB5_CC_NOSUPP; #endif } @@ -141,7 +144,7 @@ make_cred_from_ccred(krb5_context context, krb5_creds *cred) { krb5_error_code ret; - int i; + unsigned int i; memset(cred, 0, sizeof(*cred)); @@ -255,7 +258,7 @@ make_cred_from_ccred(krb5_context context, nomem: ret = ENOMEM; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); fail: krb5_free_cred_contents(context, cred); @@ -584,8 +587,10 @@ acc_close(krb5_context context, free(a->cache_name); a->cache_name = NULL; } - (*a->context->func->release)(a->context); - a->context = NULL; + if (a->context) { + (*a->context->func->release)(a->context); + a->context = NULL; + } krb5_data_free(&id->data); return 0; } @@ -620,7 +625,8 @@ acc_store_cred(krb5_context context, cc_int32 error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -653,7 +659,8 @@ acc_get_principal(krb5_context context, cc_string_t name; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -679,7 +686,8 @@ acc_get_first (krb5_context context, int32_t error; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -744,7 +752,8 @@ acc_remove_cred(krb5_context context, char *client, *server; if (a->ccache == NULL) { - krb5_set_error_string(context, "No API credential found"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); return KRB5_CC_NOTFOUND; } @@ -796,8 +805,8 @@ acc_remove_cred(krb5_context context, (*iter->func->release)(iter); if (ret) - krb5_set_error_string(context, "Can't find credential %s in cache", - server); + krb5_set_error_message(context, ret, + "Can't find credential %s in cache", server); free(server); free(client); @@ -812,7 +821,7 @@ acc_set_flags(krb5_context context, return 0; } -static krb5_error_code +static int acc_get_version(krb5_context context, krb5_ccache id) { @@ -837,7 +846,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -940,7 +949,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) } static krb5_error_code -acc_default_name(krb5_context context, char **str) +acc_get_default_name(krb5_context context, char **str) { krb5_error_code ret; cc_context_t cc; @@ -966,12 +975,30 @@ acc_default_name(krb5_context context, char **str) (*cc->func->release)(cc); if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } return 0; } +static krb5_error_code +acc_set_default(krb5_context context, krb5_ccache id) +{ + krb5_acc *a = ACACHE(id); + cc_int32 error; + + if (a->ccache == NULL) { + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "No API credential found"); + return KRB5_CC_NOTFOUND; + } + + error = (*a->ccache->func->set_default)(a->ccache); + if (error) + return translate_cc_error(context, error); + + return 0; +} /** * Variable containing the API based credential cache implemention. @@ -979,7 +1006,8 @@ acc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_acc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops = { + KRB5_CC_OPS_VERSION, "API", acc_get_name, acc_resolve, @@ -1000,5 +1028,6 @@ const krb5_cc_ops krb5_acc_ops = { acc_get_cache_next, acc_end_cache_get, acc_move, - acc_default_name + acc_get_default_name, + acc_set_default }; diff --git a/source4/heimdal/lib/krb5/addr_families.c b/source4/heimdal/lib/krb5/addr_families.c index f364f5974d..40abd874cc 100644 --- a/source4/heimdal/lib/krb5/addr_families.c +++ b/source4/heimdal/lib/krb5/addr_families.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: addr_families.c 22039 2007-11-10 11:47:35Z lha $"); +RCSID("$Id: addr_families.c 23316 2008-06-23 04:32:32Z lha $"); struct addr_operations { int af; @@ -202,7 +202,8 @@ ipv4_mask_boundary(krb5_context context, const krb5_address *inaddr, uint32_t l, h, m = 0xffffffff; if (len > 32) { - krb5_set_error_string(context, "IPv4 prefix too large (%ld)", len); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv4 prefix too large (%ld)", len); return KRB5_PROG_ATYPE_NOSUPP; } m = m << (32 - len); @@ -395,12 +396,14 @@ ipv6_mask_boundary(krb5_context context, const krb5_address *inaddr, int i, sub_len; if (len > 128) { - krb5_set_error_string(context, "IPv6 prefix too large (%ld)", len); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv6 prefix too large (%ld)", len); return KRB5_PROG_ATYPE_NOSUPP; } if (inaddr->address.length != sizeof(addr)) { - krb5_set_error_string(context, "IPv6 addr bad length"); + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "IPv6 addr bad length"); return KRB5_PROG_ATYPE_NOSUPP; } @@ -786,8 +789,9 @@ krb5_sockaddr2address (krb5_context context, { struct addr_operations *a = find_af(sa->sa_family); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - sa->sa_family); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + sa->sa_family); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->sockaddr2addr)(sa, addr); @@ -813,8 +817,9 @@ krb5_sockaddr2port (krb5_context context, { struct addr_operations *a = find_af(sa->sa_family); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - sa->sa_family); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + sa->sa_family); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->sockaddr2port)(sa, port); @@ -851,14 +856,16 @@ krb5_addr2sockaddr (krb5_context context, struct addr_operations *a = find_atype(addr->addr_type); if (a == NULL) { - krb5_set_error_string (context, "Address type %d not supported", - addr->addr_type); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address type %d not supported", + addr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if (a->addr2sockaddr == NULL) { - krb5_set_error_string (context, - "Can't convert address type %d to sockaddr", - addr->addr_type); + krb5_set_error_message (context, + KRB5_PROG_ATYPE_NOSUPP, + "Can't convert address type %d to sockaddr", + addr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } (*a->addr2sockaddr)(addr, sa, sa_size, port); @@ -935,7 +942,8 @@ krb5_h_addr2sockaddr (krb5_context context, { struct addr_operations *a = find_af(af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } (*a->h_addr2sockaddr)(addr, sa, sa_size, port); @@ -963,7 +971,8 @@ krb5_h_addr2addr (krb5_context context, { struct addr_operations *a = find_af(af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } return (*a->h_addr2addr)(haddr, addr); @@ -996,7 +1005,8 @@ krb5_anyaddr (krb5_context context, struct addr_operations *a = find_af (af); if (a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", af); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", af); return KRB5_PROG_ATYPE_NOSUPP; } @@ -1089,7 +1099,8 @@ krb5_parse_address(krb5_context context, if((*at[i].parse_addr)(context, string, &addr) == 0) { ALLOC_SEQ(addresses, 1); if (addresses->val == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } addresses->val[0] = addr; @@ -1100,9 +1111,12 @@ krb5_parse_address(krb5_context context, error = getaddrinfo (string, NULL, NULL, &ai); if (error) { + krb5_error_code ret2; save_errno = errno; - krb5_set_error_string (context, "%s: %s", string, gai_strerror(error)); - return krb5_eai_to_heim_errno(error, save_errno); + ret2 = krb5_eai_to_heim_errno(error, save_errno); + krb5_set_error_message (context, ret2, "%s: %s", + string, gai_strerror(error)); + return ret2; } n = 0; @@ -1111,7 +1125,8 @@ krb5_parse_address(krb5_context context, ALLOC_SEQ(addresses, n); if (addresses->val == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); freeaddrinfo(ai); return ENOMEM; } @@ -1154,15 +1169,17 @@ krb5_address_order(krb5_context context, struct addr_operations *a; a = find_atype(addr1->addr_type); if(a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", - addr1->addr_type); + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", + addr1->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } if(a->order_addr != NULL) return (*a->order_addr)(context, addr1, addr2); a = find_atype(addr2->addr_type); if(a == NULL) { - krb5_set_error_string (context, "Address family %d not supported", + krb5_set_error_message (context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d not supported", addr2->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } @@ -1349,7 +1366,8 @@ krb5_append_addresses(krb5_context context, if(source->len > 0) { tmp = realloc(dest->val, (dest->len + source->len) * sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string(context, "realloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "realloc: out of memory"); return ENOMEM; } dest->val = tmp; @@ -1391,13 +1409,15 @@ krb5_make_addrport (krb5_context context, *res = malloc (sizeof(**res)); if (*res == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } (*res)->addr_type = KRB5_ADDRESS_ADDRPORT; ret = krb5_data_alloc (&(*res)->address, len); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ret, + "malloc: out of memory"); free (*res); *res = NULL; return ret; @@ -1457,7 +1477,8 @@ krb5_address_prefixlen_boundary(krb5_context context, struct addr_operations *a = find_atype (inaddr->addr_type); if(a != NULL && a->mask_boundary != NULL) return (*a->mask_boundary)(context, inaddr, prefixlen, low, high); - krb5_set_error_string(context, "Address family %d doesn't support " + krb5_set_error_message(context, KRB5_PROG_ATYPE_NOSUPP, + "Address family %d doesn't support " "address mask operation", inaddr->addr_type); return KRB5_PROG_ATYPE_NOSUPP; } diff --git a/source4/heimdal/lib/krb5/auth_context.c b/source4/heimdal/lib/krb5/auth_context.c index 323f17a245..e4fb50e5b8 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 21745 2007-07-31 16:11:25Z lha $"); +RCSID("$Id: auth_context.c 23273 2008-06-23 03:25:00Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_auth_con_init(krb5_context context, @@ -43,13 +43,13 @@ krb5_auth_con_init(krb5_context context, ALLOC(p, 1); if(!p) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset(p, 0, sizeof(*p)); ALLOC(p->authenticator, 1); if (!p->authenticator) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(p); return ENOMEM; } @@ -174,7 +174,8 @@ krb5_auth_con_genaddrs(krb5_context context, len = sizeof(ss_local); if(getsockname(fd, local, &len) < 0) { ret = errno; - krb5_set_error_string (context, "getsockname: %s", + krb5_set_error_message(context, ret, + "getsockname: %s", strerror(ret)); goto out; } @@ -191,7 +192,8 @@ krb5_auth_con_genaddrs(krb5_context context, len = sizeof(ss_remote); if(getpeername(fd, remote, &len) < 0) { ret = errno; - krb5_set_error_string (context, "getpeername: %s", strerror(ret)); + krb5_set_error_message(context, ret, + "getpeername: %s", strerror(ret)); goto out; } ret = krb5_sockaddr2address (context, remote, &remote_k_address); @@ -239,7 +241,7 @@ krb5_auth_con_getaddrs(krb5_context context, krb5_free_address (context, *local_addr); *local_addr = malloc (sizeof(**local_addr)); if (*local_addr == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_copy_address(context, @@ -250,7 +252,7 @@ krb5_auth_con_getaddrs(krb5_context context, krb5_free_address (context, *remote_addr); *remote_addr = malloc (sizeof(**remote_addr)); if (*remote_addr == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); krb5_free_address (context, *local_addr); *local_addr = NULL; return ENOMEM; @@ -450,7 +452,7 @@ krb5_auth_con_getauthenticator(krb5_context context, { *authenticator = malloc(sizeof(**authenticator)); if (*authenticator == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/build_auth.c b/source4/heimdal/lib/krb5/build_auth.c index f8739c044d..fe3a5f523c 100644 --- a/source4/heimdal/lib/krb5/build_auth.c +++ b/source4/heimdal/lib/krb5/build_auth.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: build_auth.c 17033 2006-04-10 08:53:21Z lha $"); +RCSID("$Id: build_auth.c 23273 2008-06-23 03:25:00Z lha $"); static krb5_error_code make_etypelist(krb5_context context, @@ -62,7 +62,7 @@ make_etypelist(krb5_context context, ALLOC_SEQ(&ad, 1); if (ad.val == NULL) { free(buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -81,14 +81,14 @@ make_etypelist(krb5_context context, ALLOC(*auth_data, 1); if (*auth_data == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ALLOC_SEQ(*auth_data, 1); if ((*auth_data)->val == NULL) { free(buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -118,7 +118,7 @@ krb5_build_authenticator (krb5_context context, auth = calloc(1, sizeof(*auth)); if (auth == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index 5db6d2b2cf..34bfb4a350 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: cache.c 22127 2007-12-04 00:54:37Z lha $"); +RCSID("$Id: cache.c 23417 2008-07-26 18:36:33Z lha $"); /** * Add a new ccache type with operations `ops', overwriting any @@ -59,9 +59,10 @@ krb5_cc_register(krb5_context context, for(i = 0; i < context->num_cc_ops && context->cc_ops[i].prefix; i++) { if(strcmp(context->cc_ops[i].prefix, ops->prefix) == 0) { if(!override) { - krb5_set_error_string(context, - "ccache type %s already exists", - ops->prefix); + krb5_set_error_message(context, + KRB5_CC_TYPE_EXISTS, + "ccache type %s already exists", + ops->prefix); return KRB5_CC_TYPE_EXISTS; } break; @@ -72,7 +73,8 @@ krb5_cc_register(krb5_context context, (context->num_cc_ops + 1) * sizeof(*context->cc_ops)); if(o == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } context->num_cc_ops++; @@ -98,7 +100,7 @@ _krb5_cc_allocate(krb5_context context, p = malloc (sizeof(*p)); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } p->ops = ops; @@ -166,7 +168,8 @@ krb5_cc_resolve(krb5_context context, if (strchr (name, ':') == NULL) return allocate_ccache (context, &krb5_fcc_ops, name, id); else { - krb5_set_error_string(context, "unknown ccache type %s", name); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "unknown ccache type %s", name); return KRB5_CC_UNKNOWN_TYPE; } } @@ -204,16 +207,14 @@ 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 = KRB5_DEFAULT_CCTYPE; + const krb5_cc_ops *ops; krb5_error_code ret; - 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; - } + ops = krb5_cc_get_prefix_ops(context, type); + if (ops == NULL) { + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "Credential cache type %s is unknown", type); + return KRB5_CC_UNKNOWN_TYPE; } ret = _krb5_cc_allocate(context, ops, id); @@ -270,18 +271,20 @@ krb5_cc_get_full_name(krb5_context context, type = krb5_cc_get_type(context, id); if (type == NULL) { - krb5_set_error_string(context, "cache have no name of type"); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "cache have no name of type"); return KRB5_CC_UNKNOWN_TYPE; } name = krb5_cc_get_name(context, id); if (name == NULL) { - krb5_set_error_string(context, "cache of type %s have no name", type); + krb5_set_error_message(context, KRB5_CC_BADNAME, + "cache of type %s have no name", type); return KRB5_CC_BADNAME; } if (asprintf(str, "%s:%s", type, name) == -1) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); *str = NULL; return ENOMEM; } @@ -327,7 +330,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) if (tmp2 == NULL) { free(*res); *res = NULL; - krb5_set_error_string(context, "variable missing }"); + krb5_set_error_message(context, KRB5_CONFIG_BADFORMAT, + "variable missing }"); return KRB5_CONFIG_BADFORMAT; } if (strncasecmp(tmp, "%{uid}", 6) == 0) @@ -337,10 +341,11 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) else { free(*res); *res = NULL; - krb5_set_error_string(context, - "expand default cache unknown " - "variable \"%.*s\"", - (int)(tmp2 - tmp) - 2, tmp + 2); + krb5_set_error_message(context, + KRB5_CONFIG_BADFORMAT, + "expand default cache unknown " + "variable \"%.*s\"", + (int)(tmp2 - tmp) - 2, tmp + 2); return KRB5_CONFIG_BADFORMAT; } str = tmp2 + 1; @@ -351,7 +356,7 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) if (append == NULL) { free(*res); *res = NULL; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -361,7 +366,8 @@ _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) free(append); free(*res); *res = NULL; - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } *res = tmp; @@ -406,11 +412,29 @@ environment_changed(krb5_context context) } /** - * Set the default cc name for `context' to `name'. + * Switch the default default credential cache for a specific + * credcache type (and name for some implementations). + * + * @return Returns 0 or an error code. * * @ingroup krb5_ccache */ +krb5_error_code +krb5_cc_switch(krb5_context context, krb5_ccache id) +{ + + if (id->ops->set_default == NULL) + return 0; + + return (*id->ops->set_default)(context, id); +} + +/** + * 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) @@ -440,7 +464,19 @@ krb5_cc_set_default_name(krb5_context context, const char *name) } if (e == NULL) { const krb5_cc_ops *ops = KRB5_DEFAULT_CCTYPE; - ret = (*ops->default_name)(context, &p); + e = krb5_config_get_string(context, NULL, "libdefaults", + "default_cc_type", NULL); + if (e) { + ops = krb5_cc_get_prefix_ops(context, e); + if (ops == NULL) { + krb5_set_error_message(context, + KRB5_CC_UNKNOWN_TYPE, + "Credential cache type %s " + "is unknown", e); + return KRB5_CC_UNKNOWN_TYPE; + } + } + ret = (*ops->get_default_name)(context, &p); if (ret) return ret; } @@ -452,7 +488,7 @@ krb5_cc_set_default_name(krb5_context context, const char *name) } if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -499,7 +535,7 @@ krb5_cc_default(krb5_context context, const char *p = krb5_cc_default_name(context); if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return krb5_cc_resolve(context, p, id); @@ -728,9 +764,10 @@ krb5_cc_remove_cred(krb5_context context, krb5_creds *cred) { if(id->ops->remove_cred == NULL) { - krb5_set_error_string(context, - "ccache %s does not support remove_cred", - id->ops->prefix); + krb5_set_error_message(context, + EACCES, + "ccache %s does not support remove_cred", + id->ops->prefix); return EACCES; /* XXX */ } return (*id->ops->remove_cred)(context, id, which, cred); @@ -846,10 +883,12 @@ krb5_cc_clear_mcred(krb5_creds *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. 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. If prefix the argument is NULL, the default ccache + * implemtation is returned. + + * @return Returns NULL if ops not found. * * @ingroup krb5_ccache */ @@ -861,12 +900,14 @@ krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) char *p, *p1; int i; + if (prefix == NULL) + return KRB5_DEFAULT_CCTYPE; if (prefix[0] == '/') return &krb5_fcc_ops; p = strdup(prefix); if (p == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return NULL; } p1 = strchr(p, ':'); @@ -911,20 +952,22 @@ krb5_cc_cache_get_first (krb5_context context, ops = krb5_cc_get_prefix_ops(context, type); if (ops == NULL) { - krb5_set_error_string(context, "Unknown type \"%s\" when iterating " - "trying to iterate the credential caches", type); + krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, + "Unknown type \"%s\" when iterating " + "trying to iterate the credential caches", type); return KRB5_CC_UNKNOWN_TYPE; } if (ops->get_cache_first == NULL) { - krb5_set_error_string(context, "Credential cache type %s doesn't support " - "iterations over caches", ops->prefix); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Credential cache type %s doesn't support " + "iterations over caches", ops->prefix); return KRB5_CC_NOSUPP; } *cursor = calloc(1, sizeof(**cursor)); if (*cursor == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1028,8 +1071,10 @@ krb5_cc_cache_match (krb5_context context, krb5_unparse_name(context, client, &str); - krb5_set_error_string(context, "Principal %s not found in a " - "credential cache", str ? str : "<out of memory>"); + krb5_set_error_message(context, KRB5_CC_NOTFOUND, + "Principal %s not found in a " + "credential cache", + str ? str : "<out of memory>"); if (str) free(str); return KRB5_CC_NOTFOUND; @@ -1059,8 +1104,9 @@ 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"); + krb5_set_error_message(context, KRB5_CC_NOSUPP, + "Moving credentials between diffrent " + "types not yet supported"); return KRB5_CC_NOSUPP; } @@ -1071,3 +1117,123 @@ krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to) } return ret; } + +#define KRB5_CONF_NAME "@krb5_ccache_conf_data" + +static krb5_error_code +build_conf_principals(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_creds *cred) +{ + krb5_principal client; + krb5_error_code ret; + char *pname = NULL; + + memset(cred, 0, sizeof(*cred)); + + ret = krb5_cc_get_principal(context, id, &client); + if (ret) + return ret; + + if (principal) { + ret = krb5_unparse_name(context, principal, &pname); + if (ret) + return ret; + } + + ret = krb5_make_principal(context, &cred->server, + krb5_principal_get_realm(context, client), + KRB5_CONF_NAME, name, pname, NULL); + free(pname); + if (ret) { + krb5_free_principal(context, client); + return ret; + } + ret = krb5_copy_principal(context, client, &cred->client); + krb5_free_principal(context, client); + return ret; +} + +/** + * Store some configuration for the credential cache in the cache. + * Existing configuration under the same name is over-written. + * + * @param context a Keberos context + * @param id the credential cache to store the data for + * @param principal configuration for a specific principal, if + * NULL, global for the whole cache. + * @param name name under which the configuraion is stored. + * @param data data to store + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_set_config(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_data *data) +{ + krb5_error_code ret; + krb5_creds cred; + + ret = build_conf_principals(context, id, principal, name, &cred); + if (ret) + goto out; + + /* Remove old configuration */ + ret = krb5_cc_remove_cred(context, id, 0, &cred); + if (ret) + goto out; + + /* not that anyone care when this expire */ + cred.times.authtime = time(NULL); + cred.times.endtime = cred.times.authtime + 3600 * 24 * 30; + + ret = krb5_data_copy(&cred.ticket, data->data, data->length); + if (ret) + goto out; + + ret = krb5_cc_store_cred(context, id, &cred); + +out: + krb5_free_cred_contents (context, &cred); + return ret; +} + +/** + * Get some configuration for the credential cache in the cache. + * + * @param context a Keberos context + * @param id the credential cache to store the data for + * @param principal configuration for a specific principal, if + * NULL, global for the whole cache. + * @param name name under which the configuraion is stored. + * @param data data to fetched, free with krb5_data_free() + */ + + +krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_get_config(krb5_context context, krb5_ccache id, + krb5_const_principal principal, + const char *name, krb5_data *data) +{ + krb5_creds mcred, cred; + krb5_error_code ret; + + memset(&cred, 0, sizeof(cred)); + krb5_data_zero(data); + + ret = build_conf_principals(context, id, principal, name, &mcred); + if (ret) + goto out; + + ret = krb5_cc_retrieve_cred(context, id, 0, &mcred, &cred); + if (ret) + goto out; + + ret = krb5_data_copy(data, cred.ticket.data, cred.ticket.length); + +out: + krb5_free_cred_contents (context, &cred); + krb5_free_cred_contents (context, &mcred); + return ret; +} + diff --git a/source4/heimdal/lib/krb5/changepw.c b/source4/heimdal/lib/krb5/changepw.c index 703cf43eb6..ac1a2d312e 100644 --- a/source4/heimdal/lib/krb5/changepw.c +++ b/source4/heimdal/lib/krb5/changepw.c @@ -33,7 +33,11 @@ #include <krb5_locl.h> -RCSID("$Id: changepw.c 21505 2007-07-12 12:28:38Z lha $"); +RCSID("$Id: changepw.c 23445 2008-07-27 12:08:03Z lha $"); + +#undef __attribute__ +#define __attribute__(X) + static void str2data (krb5_data *d, @@ -141,7 +145,8 @@ chgpw_send_request (krb5_context context, if (sendmsg (sock, &msghdr, 0) < 0) { ret = errno; - krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret)); + krb5_set_error_message(context, ret, "sendmsg %s: %s", + host, strerror(ret)); } krb5_data_free (&krb_priv_data); @@ -250,7 +255,8 @@ setpw_send_request (krb5_context context, if (sendmsg (sock, &msghdr, 0) < 0) { ret = errno; - krb5_set_error_string(context, "sendmsg %s: %s", host, strerror(ret)); + krb5_set_error_message(context, ret, "sendmsg %s: %s", + host, strerror(ret)); } krb5_data_free (&krb_priv_data); @@ -286,11 +292,12 @@ process_reply (krb5_context context, 0, NULL, NULL); if (ret < 0) { save_errno = errno; - krb5_set_error_string(context, "recvfrom %s: %s", - host, strerror(save_errno)); + krb5_set_error_message(context, save_errno, + "recvfrom %s: %s", + host, strerror(save_errno)); return save_errno; } else if (ret == 0) { - krb5_set_error_string(context, "recvfrom timeout %s", host); + krb5_set_error_message(context, 1,"recvfrom timeout %s", host); return 1; } len += ret; @@ -304,16 +311,18 @@ process_reply (krb5_context context, break; } if (len == sizeof(reply)) { - krb5_set_error_string(context, "message too large from %s", - host); + krb5_set_error_message(context, ENOMEM, + "message too large from %s", + host); return ENOMEM; } } else { ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL); if (ret < 0) { save_errno = errno; - krb5_set_error_string(context, "recvfrom %s: %s", - host, strerror(save_errno)); + krb5_set_error_message(context, save_errno, + "recvfrom %s: %s", + host, strerror(save_errno)); return save_errno; } len = ret; @@ -522,7 +531,7 @@ change_password_loop (krb5_context context, krb5_krbhst_handle handle = NULL; krb5_krbhst_info *hi; int sock; - int i; + unsigned int i; int done = 0; krb5_realm realm; @@ -571,6 +580,7 @@ change_password_loop (krb5_context context, sock = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (sock < 0) continue; + rk_cloexec(sock); ret = connect(sock, a->ai_addr, a->ai_addrlen); if (ret < 0) { @@ -607,8 +617,9 @@ change_password_loop (krb5_context context, } if (sock >= FD_SETSIZE) { - krb5_set_error_string(context, "fd %d too large", sock); ret = ERANGE; + krb5_set_error_message(context, ret, + "fd %d too large", sock); close (sock); goto out; } @@ -647,24 +658,32 @@ change_password_loop (krb5_context context, out: krb5_krbhst_free (context, handle); krb5_auth_con_free (context, auth_context); - if (done) - return 0; - else { - if (ret == KRB5_KDC_UNREACH) { - krb5_set_error_string(context, - "unable to reach any changepw server " - " in realm %s", realm); - *result_code = KRB5_KPASSWD_HARDERROR; - } - return ret; + + if (ret == KRB5_KDC_UNREACH) { + krb5_set_error_message(context, + ret, + "unable to reach any changepw server " + " in realm %s", realm); + *result_code = KRB5_KPASSWD_HARDERROR; } + return ret; } +#ifndef HEIMDAL_SMALLER -/* - * change the password using the credentials in `creds' (for the - * principal indicated in them) to `newpw', storing the result of - * the operation in `result_*' and an error code or 0. +/** + * krb5_change_password() is deprecated, use krb5_set_password(). + * + * @param context a Keberos context + * @param creds + * @param newpw + * @param result_code + * @param result_code_string + * @param result_string + * + * @return On sucess password is changed. + + * @ingroup @krb5_deprecated */ krb5_error_code KRB5_LIB_FUNCTION @@ -674,6 +693,7 @@ krb5_change_password (krb5_context context, int *result_code, krb5_data *result_code_string, krb5_data *result_string) + __attribute__((deprecated)) { struct kpwd_proc *p = find_chpw_proto("change password"); @@ -688,9 +708,24 @@ krb5_change_password (krb5_context context, result_code, result_code_string, result_string, p); } +#endif /* HEIMDAL_SMALLER */ -/* +/** + * Change passwrod using creds. + * + * @param context a Keberos context + * @param creds The initial kadmin/passwd for the principal or an admin principal + * @param newpw The new password to set + * @param targprinc if unset, the default principal is used. + * @param result_code Result code, KRB5_KPASSWD_SUCCESS is when password is changed. + * @param result_code_string binary message from the server, contains + * at least the result_code. + * @param result_string A message from the kpasswd service or the + * library in human printable form. The string is NUL terminated. * + * @return On sucess and *result_code is KRB5_KPASSWD_SUCCESS, the password is changed. + + * @ingroup @krb5 */ krb5_error_code KRB5_LIB_FUNCTION @@ -707,8 +742,8 @@ krb5_set_password(krb5_context context, int i; *result_code = KRB5_KPASSWD_MALFORMED; - result_code_string->data = result_string->data = NULL; - result_code_string->length = result_string->length = 0; + krb5_data_zero(result_code_string); + krb5_data_zero(result_string); if (targprinc == NULL) { ret = krb5_get_default_principal(context, &principal); @@ -732,6 +767,8 @@ krb5_set_password(krb5_context context, return ret; } +#ifndef HEIMDAL_SMALLER + /* * */ @@ -797,6 +834,8 @@ krb5_set_password_using_ccache(krb5_context context, return ret; } +#endif /* !HEIMDAL_SMALLER */ + /* * */ diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index ac5eba39dc..bf3c432397 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -32,7 +32,7 @@ */ #include "krb5_locl.h" -RCSID("$Id: config_file.c 19213 2006-12-04 23:36:36Z lha $"); +RCSID("$Id: config_file.c 23280 2008-06-23 03:26:18Z lha $"); #ifndef HAVE_NETINFO @@ -295,7 +295,8 @@ krb5_config_parse_string_multi(krb5_context context, ret = krb5_config_parse_debug (&f, res, &lineno, &str); if (ret) { - krb5_set_error_string (context, "%s:%u: %s", "<constant>", lineno, str); + krb5_set_error_message (context, ret, "%s:%u: %s", + "<constant>", lineno, str); return ret; } return 0; @@ -314,14 +315,15 @@ krb5_config_parse_file_multi (krb5_context context, f.s = NULL; if(f.f == NULL) { ret = errno; - krb5_set_error_string (context, "open %s: %s", fname, strerror(ret)); + krb5_set_error_message (context, ret, "open %s: %s", + fname, strerror(ret)); return ret; } ret = krb5_config_parse_debug (&f, res, &lineno, &str); fclose(f.f); if (ret) { - krb5_set_error_string (context, "%s:%u: %s", fname, lineno, str); + krb5_set_error_message (context, ret, "%s:%u: %s", fname, lineno, str); return ret; } return 0; diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index 5188a1d3a8..8fffb0f402 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -33,11 +33,11 @@ #include "krb5_locl.h" -RCSID("$Id: constants.c 14253 2004-09-23 07:57:37Z joda $"); +RCSID("$Id: constants.c 23026 2008-04-17 10:02:03Z lha $"); -const char *krb5_config_file = +KRB5_LIB_VARIABLE const char *krb5_config_file = #ifdef __APPLE__ "/Library/Preferences/edu.mit.Kerberos:" #endif SYSCONFDIR "/krb5.conf:/etc/krb5.conf"; -const char *krb5_defkeyname = KEYTAB_DEFAULT; +KRB5_LIB_VARIABLE const char *krb5_defkeyname = KEYTAB_DEFAULT; diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 256783310e..543dba396d 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <com_err.h> -RCSID("$Id: context.c 22293 2007-12-14 05:25:59Z lha $"); +RCSID("$Id: context.c 23420 2008-07-26 18:37:48Z lha $"); #define INIT_FIELD(C, T, E, D, F) \ (C)->E = krb5_config_get_ ## T ## _default ((C), NULL, (D), \ @@ -68,7 +68,7 @@ set_etypes (krb5_context context, etypes = malloc((i+1) * sizeof(*etypes)); if (etypes == NULL) { krb5_config_free_strings (etypes_str); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for(j = 0, k = 0; j < i; j++) { @@ -246,6 +246,9 @@ krb5_init_context(krb5_context *context) krb5_cc_register(p, &krb5_acc_ops, TRUE); krb5_cc_register(p, &krb5_fcc_ops, TRUE); krb5_cc_register(p, &krb5_mcc_ops, TRUE); +#if 0 + krb5_cc_register(p, &krb5_scc_ops, TRUE); +#endif #ifdef HAVE_KCM krb5_cc_register(p, &krb5_kcm_ops, TRUE); #endif @@ -257,8 +260,6 @@ krb5_init_context(krb5_context *context) krb5_kt_register (p, &krb5_javakt_ops); krb5_kt_register (p, &krb5_mkt_ops); krb5_kt_register (p, &krb5_akf_ops); - krb5_kt_register (p, &krb4_fkt_ops); - krb5_kt_register (p, &krb5_srvtab_fkt_ops); krb5_kt_register (p, &krb5_any_ops); out: @@ -552,7 +553,7 @@ default_etypes(krb5_context context, krb5_enctype **etype) ep = realloc(e, (n + 2) * sizeof(*e)); if (ep == NULL) { free(e); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e = ep; @@ -594,7 +595,7 @@ krb5_set_default_in_tkt_etypes(krb5_context context, ++i; ALLOC(p, i); if(!p) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memmove(p, etypes, i * sizeof(krb5_enctype)); @@ -623,26 +624,26 @@ krb5_error_code KRB5_LIB_FUNCTION krb5_get_default_in_tkt_etypes(krb5_context context, krb5_enctype **etypes) { - krb5_enctype *p; - int i; - krb5_error_code ret; - - if(context->etypes) { - for(i = 0; context->etypes[i]; i++); - ++i; - ALLOC(p, i); - if(!p) { - krb5_set_error_string (context, "malloc: out of memory"); - return ENOMEM; + krb5_enctype *p; + int i; + krb5_error_code ret; + + if(context->etypes) { + for(i = 0; context->etypes[i]; i++); + ++i; + ALLOC(p, i); + if(!p) { + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + memmove(p, context->etypes, i * sizeof(krb5_enctype)); + } else { + ret = default_etypes(context, &p); + if (ret) + return ret; } - memmove(p, context->etypes, i * sizeof(krb5_enctype)); - } else { - ret = default_etypes(context, &p); - if (ret) - return ret; - } - *etypes = p; - return 0; + *etypes = p; + return 0; } /** @@ -776,7 +777,7 @@ krb5_set_extra_addresses(krb5_context context, const krb5_addresses *addresses) if(context->extra_addresses == NULL) { context->extra_addresses = malloc(sizeof(*context->extra_addresses)); if(context->extra_addresses == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -858,7 +859,7 @@ krb5_set_ignore_addresses(krb5_context context, const krb5_addresses *addresses) if(context->ignore_addresses == NULL) { context->ignore_addresses = malloc(sizeof(*context->ignore_addresses)); if(context->ignore_addresses == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } @@ -986,7 +987,7 @@ krb5_get_dns_canonicalize_hostname (krb5_context 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. + * @return returns zero * * @ingroup krb5 */ @@ -1002,6 +1003,27 @@ krb5_get_kdc_sec_offset (krb5_context context, int32_t *sec, int32_t *usec) } /** + * Set 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 returns zero + * + * @ingroup krb5 + */ + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_kdc_sec_offset (krb5_context context, int32_t sec, int32_t usec) +{ + context->kdc_sec_offset = sec; + if (usec >= 0) + context->kdc_usec_offset = usec; + return 0; +} + +/** * Get max time skew allowed. * * @param context Kerberos 5 context. diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c index b2af0187ea..07943efb28 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 22050 2007-11-11 11:20:46Z lha $"); +RCSID("$Id: convert_creds.c 23280 2008-06-23 03:26:18Z lha $"); #include "krb5-v4compat.h" @@ -97,7 +97,7 @@ krb524_convert_creds_kdc(krb5_context context, sp = krb5_storage_from_mem(reply.data, reply.length); if(sp == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); goto out2; } krb5_ret_int32(sp, &tmp); @@ -132,8 +132,8 @@ krb524_convert_creds_kdc(krb5_context context, goto out; memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8); } else { - krb5_set_error_string(context, "converting credentials: %s", - krb5_get_err_text(context, ret)); + krb5_set_error_message (context, ret, "converting credentials: %s", + krb5_get_err_text(context, ret)); } out: krb5_storage_free(sp); diff --git a/source4/heimdal/lib/krb5/copy_host_realm.c b/source4/heimdal/lib/krb5/copy_host_realm.c index 8c4f39b4ac..cbe333850c 100644 --- a/source4/heimdal/lib/krb5/copy_host_realm.c +++ b/source4/heimdal/lib/krb5/copy_host_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: copy_host_realm.c 22057 2007-11-11 15:13:13Z lha $"); +RCSID("$Id: copy_host_realm.c 23280 2008-06-23 03:26:18Z lha $"); /** * Copy the list of realms from `from' to `to'. @@ -53,24 +53,23 @@ krb5_copy_host_realm(krb5_context context, const krb5_realm *from, krb5_realm **to) { - int n, i; + unsigned int n, i; const krb5_realm *p; - for (n = 0, p = from; *p != NULL; ++p) + for (n = 1, p = from; *p != NULL; ++p) ++n; - ++n; - *to = malloc (n * sizeof(**to)); + + *to = calloc (n, sizeof(**to)); if (*to == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - for (i = 0; i < n; ++i) - (*to)[i] = NULL; + for (i = 0, p = from; *p != NULL; ++p, ++i) { (*to)[i] = strdup(*p); if ((*to)[i] == NULL) { krb5_free_host_realm (context, *to); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } } diff --git a/source4/heimdal/lib/krb5/crc.c b/source4/heimdal/lib/krb5/crc.c index 072c29d689..e8ddecf7ba 100644 --- a/source4/heimdal/lib/krb5/crc.c +++ b/source4/heimdal/lib/krb5/crc.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: crc.c 17442 2006-05-05 09:31:15Z lha $"); +RCSID("$Id: crc.c 22862 2008-04-07 18:49:55Z lha $"); static u_long table[256]; @@ -44,7 +44,7 @@ _krb5_crc_init_table(void) { static int flag = 0; unsigned long crc, poly; - int i, j; + unsigned int i, j; if(flag) return; poly = CRC_GEN; diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index 17ef46dfa3..938ec294a4 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -33,11 +33,13 @@ #include "krb5_locl.h" -RCSID("$Id: creds.c 22062 2007-11-11 15:41:50Z lha $"); +RCSID("$Id: creds.c 23280 2008-06-23 03:26:18Z lha $"); #undef __attribute__ #define __attribute__(X) +#ifndef HEIMDAL_SMALLER + /* keep this for compatibility with older code */ krb5_error_code KRB5_LIB_FUNCTION __attribute__((deprecated)) krb5_free_creds_contents (krb5_context context, krb5_creds *c) @@ -45,6 +47,8 @@ krb5_free_creds_contents (krb5_context context, krb5_creds *c) return krb5_free_cred_contents (context, c); } +#endif /* HEIMDAL_SMALLER */ + /** * Free content of krb5_creds. * @@ -152,7 +156,7 @@ krb5_copy_creds (krb5_context context, c = malloc (sizeof (*c)); if (c == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset (c, 0, sizeof(*c)); diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 2e63490946..e91cb9391a 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -32,7 +32,8 @@ */ #include "krb5_locl.h" -RCSID("$Id: crypto.c 22200 2007-12-07 13:48:01Z lha $"); +RCSID("$Id: crypto.c 23454 2008-07-27 12:11:44Z lha $"); +#include <pkinit_asn1.h> #undef CRYPTO_DEBUG #ifdef CRYPTO_DEBUG @@ -111,7 +112,6 @@ struct checksum_type { struct encryption_type { krb5_enctype type; const char *name; - heim_oid *oid; size_t blocksize; size_t padsize; size_t confoundersize; @@ -178,7 +178,7 @@ static void krb5_DES_schedule(krb5_context context, struct key_data *key) { - DES_set_key(key->key->keyvalue.data, key->schedule->data); + DES_set_key_unchecked(key->key->keyvalue.data, key->schedule->data); } #ifdef ENABLE_AFS_STRING_TO_KEY @@ -245,12 +245,12 @@ krb5_DES_AFS3_Transarc_string_to_key (krb5_data pw, memcpy(&ivec, "kerberos", 8); memcpy(&temp_key, "kerberos", 8); DES_set_odd_parity (&temp_key); - DES_set_key (&temp_key, &schedule); + DES_set_key_unchecked (&temp_key, &schedule); DES_cbc_cksum ((void*)password, &ivec, passlen, &schedule, &ivec); memcpy(&temp_key, &ivec, 8); DES_set_odd_parity (&temp_key); - DES_set_key (&temp_key, &schedule); + DES_set_key_unchecked (&temp_key, &schedule); DES_cbc_cksum ((void*)password, key, passlen, &schedule, &ivec); memset(&schedule, 0, sizeof(schedule)); memset(&temp_key, 0, sizeof(temp_key)); @@ -305,7 +305,7 @@ DES_string_to_key_int(unsigned char *data, size_t length, DES_cblock *key) DES_set_odd_parity(key); if(DES_is_weak_key(key)) (*key)[7] ^= 0xF0; - DES_set_key(key, &schedule); + DES_set_key_unchecked(key, &schedule); DES_cbc_cksum((void*)data, key, length, &schedule, key); memset(&schedule, 0, sizeof(schedule)); DES_set_odd_parity(key); @@ -338,7 +338,7 @@ krb5_DES_string_to_key(krb5_context context, len = password.length + salt.saltvalue.length; s = malloc(len); if(len > 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(s, password.data, password.length); @@ -390,9 +390,9 @@ DES3_schedule(krb5_context context, { DES_cblock *k = key->key->keyvalue.data; DES_key_schedule *s = key->schedule->data; - DES_set_key(&k[0], &s[0]); - DES_set_key(&k[1], &s[1]); - DES_set_key(&k[2], &s[2]); + DES_set_key_unchecked(&k[0], &s[0]); + DES_set_key_unchecked(&k[1], &s[1]); + DES_set_key_unchecked(&k[2], &s[2]); } /* @@ -430,7 +430,7 @@ DES3_string_to_key(krb5_context context, len = password.length + salt.saltvalue.length; str = malloc(len); if(len != 0 && str == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(str, password.data, password.length); @@ -444,7 +444,7 @@ DES3_string_to_key(krb5_context context, if (ret) { memset(str, 0, len); free(str); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message (context, ret, "malloc: out of memory"); return ret; } @@ -453,7 +453,7 @@ DES3_string_to_key(krb5_context context, DES_set_odd_parity(keys + i); if(DES_is_weak_key(keys + i)) xor(keys + i, (const unsigned char*)"\0\0\0\0\0\0\0\xf0"); - DES_set_key(keys + i, &s[i]); + DES_set_key_unchecked(keys + i, &s[i]); } memset(&ivec, 0, sizeof(ivec)); DES_ede3_cbc_encrypt(tmp, @@ -491,7 +491,7 @@ DES3_string_to_key_derived(krb5_context context, s = malloc(len); if(len != 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(s, password.data, password.length); @@ -560,35 +560,49 @@ ARCFOUR_string_to_key(krb5_context context, krb5_data opaque, krb5_keyblock *key) { - char *s, *p; - size_t len; - int i; - MD4_CTX m; krb5_error_code ret; + uint16_t *s; + size_t len, i; + MD4_CTX m; - len = 2 * password.length; - s = malloc (len); + ret = wind_utf8ucs2_length(password.data, &len); + if (ret) { + krb5_set_error_message (context, ret, "Password not an UCS2 string"); + return ret; + } + + s = malloc (len * sizeof(s[0])); if (len != 0 && s == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); - ret = ENOMEM; - goto out; + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); + return ENOMEM; } - for (p = s, i = 0; i < password.length; ++i) { - *p++ = ((char *)password.data)[i]; - *p++ = 0; + + ret = wind_utf8ucs2(password.data, s, &len); + if (ret) { + krb5_set_error_message (context, ret, "Password not an UCS2 string"); + goto out; } + + /* LE encoding */ MD4_Init (&m); - MD4_Update (&m, s, len); + for (i = 0; i < len; i++) { + unsigned char p; + p = (s[i] & 0xff); + MD4_Update (&m, &p, 1); + p = (s[i] >> 8) & 0xff; + MD4_Update (&m, &p, 1); + } + key->keytype = enctype; ret = krb5_data_alloc (&key->keyvalue, 16); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); goto out; } MD4_Final (key->keyvalue.data, &m); - memset (s, 0, len); ret = 0; out: + memset (s, 0, len); free (s); return ret; } @@ -628,13 +642,13 @@ AES_string_to_key(krb5_context context, kd.schedule = NULL; ALLOC(kd.key, 1); if(kd.key == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } kd.key->keytype = enctype; ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); if (ret) { - krb5_set_error_string(context, "Failed to allocate pkcs5 key"); + krb5_set_error_message (context, ret, "malloc: out of memory"); return ret; } @@ -644,7 +658,8 @@ AES_string_to_key(krb5_context context, et->keytype->size, kd.key->keyvalue.data); if (ret != 1) { free_key_data(context, &kd); - krb5_set_error_string(context, "Error calculating s2k"); + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "Error calculating s2k"); return KRB5_PROG_KEYTYPE_NOSUPP; } @@ -847,21 +862,24 @@ krb5_salttype_to_string (krb5_context context, e = _find_enctype (etype); if (e == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { if (st->type == stype) { *string = strdup (st->name); if (*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } return 0; } } - krb5_set_error_string(context, "salttype %d not supported", stype); + krb5_set_error_message (context, HEIM_ERR_SALTTYPE_NOSUPP, + "salttype %d not supported", stype); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -876,8 +894,9 @@ krb5_string_to_salttype (krb5_context context, e = _find_enctype (etype); if (e == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } for (st = e->keytype->string_to_key; st && st->type; st++) { @@ -886,7 +905,8 @@ krb5_string_to_salttype (krb5_context context, return 0; } } - krb5_set_error_string(context, "salttype %s not supported", string); + krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP, + "salttype %s not supported", string); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -988,16 +1008,18 @@ krb5_string_to_key_data_salt_opaque (krb5_context context, struct encryption_type *et =_find_enctype(enctype); struct salt_type *st; if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - enctype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); return KRB5_PROG_ETYPE_NOSUPP; } for(st = et->keytype->string_to_key; st && st->type; st++) if(st->type == salt.salttype) return (*st->string_to_key)(context, enctype, password, salt, opaque, key); - krb5_set_error_string(context, "salt type %d not supported", - salt.salttype); + krb5_set_error_message(context, HEIM_ERR_SALTTYPE_NOSUPP, + "salt type %d not supported", + salt.salttype); return HEIM_ERR_SALTTYPE_NOSUPP; } @@ -1042,12 +1064,13 @@ krb5_keytype_to_string(krb5_context context, { struct key_type *kt = _find_keytype(keytype); if(kt == NULL) { - krb5_set_error_string(context, "key type %d not supported", keytype); + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "key type %d not supported", keytype); return KRB5_PROG_KEYTYPE_NOSUPP; } *string = strdup(kt->name); if(*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -1058,13 +1081,24 @@ krb5_string_to_keytype(krb5_context context, const char *string, krb5_keytype *keytype) { + char *end; int i; + for(i = 0; i < num_keytypes; i++) if(strcasecmp(keytypes[i]->name, string) == 0){ *keytype = keytypes[i]->type; return 0; } - krb5_set_error_string(context, "key type %s not supported", string); + + /* check if the enctype is a number */ + *keytype = strtol(string, &end, 0); + if(*end == '\0' && *keytype != 0) { + if (krb5_enctype_valid(context, *keytype) == 0) + return 0; + } + + krb5_set_error_message(context, KRB5_PROG_KEYTYPE_NOSUPP, + "key type %s not supported", string); return KRB5_PROG_KEYTYPE_NOSUPP; } @@ -1075,8 +1109,9 @@ krb5_enctype_keysize(krb5_context context, { struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } *keysize = et->keytype->size; @@ -1090,7 +1125,8 @@ krb5_enctype_keybits(krb5_context context, { struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", type); return KRB5_PROG_ETYPE_NOSUPP; } @@ -1106,8 +1142,9 @@ krb5_generate_random_keyblock(krb5_context context, krb5_error_code ret; struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); @@ -1136,7 +1173,7 @@ _key_schedule(krb5_context context, return 0; ALLOC(key->schedule, 1); if(key->schedule == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_data_alloc(key->schedule, kt->schedule_size); @@ -1481,8 +1518,9 @@ krb5_hmac(krb5_context context, krb5_error_code ret; if (c == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - cktype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + cktype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1797,7 +1835,7 @@ get_checksum_key(krb5_context context, *key = _new_derived_key(crypto, 0xff/* KRB5_KU_RFC1510_VARIANT */); if(*key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_copy_keyblock(context, crypto->key.key, &(*key)->key); @@ -1832,9 +1870,10 @@ create_checksum (krb5_context context, } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { - krb5_set_error_string (context, "Checksum type %s is keyed " - "but no crypto context (key) was passed in", - ct->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "Checksum type %s is keyed " + "but no crypto context (key) was passed in", + ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) { @@ -1880,8 +1919,9 @@ krb5_create_checksum(krb5_context context, } if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1911,7 +1951,8 @@ verify_checksum(krb5_context context, ct = _find_checksum(cksum->cksumtype); if (ct == NULL || (ct->flags & F_DISABLED)) { - krb5_set_error_string (context, "checksum type %d not supported", + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1921,9 +1962,10 @@ verify_checksum(krb5_context context, } keyed_checksum = (ct->flags & F_KEYED) != 0; if(keyed_checksum && crypto == NULL) { - krb5_set_error_string (context, "Checksum type %s is keyed " - "but no crypto context (key) was passed in", - ct->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "Checksum type %s is keyed " + "but no crypto context (key) was passed in", + ct->name); return KRB5_PROG_SUMTYPE_NOSUPP; /* XXX */ } if(keyed_checksum) @@ -1963,8 +2005,9 @@ krb5_verify_checksum(krb5_context context, ct = _find_checksum(cksum->cksumtype); if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - cksum->cksumtype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + cksum->cksumtype); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -1992,7 +2035,8 @@ krb5_crypto_get_checksum_type(krb5_context context, } if (ct == NULL) { - krb5_set_error_string (context, "checksum type not found"); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type not found"); return KRB5_PROG_SUMTYPE_NOSUPP; } @@ -2009,8 +2053,9 @@ krb5_checksumsize(krb5_context context, { struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } *size = ct->checksumsize; @@ -2024,8 +2069,9 @@ krb5_checksum_is_keyed(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_KEYED; @@ -2038,8 +2084,9 @@ krb5_checksum_is_collision_proof(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } return ct->flags & F_CPROOF; @@ -2052,8 +2099,9 @@ krb5_checksum_disable(krb5_context context, struct checksum_type *ct = _find_checksum(type); if(ct == NULL) { if (context) - krb5_set_error_string (context, "checksum type %d not supported", - type); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + type); return KRB5_PROG_SUMTYPE_NOSUPP; } ct->flags |= F_DISABLED; @@ -2478,7 +2526,7 @@ AES_PRF(krb5_context context, result.cksumtype = ct->type; ret = krb5_data_alloc(&result.checksum, ct->checksumsize); if (ret) { - krb5_set_error_string(context, "out memory"); + krb5_set_error_message(context, ret, "out memory"); return ret; } @@ -2519,7 +2567,6 @@ AES_PRF(krb5_context context, static struct encryption_type enctype_null = { ETYPE_NULL, "null", - NULL, 1, 1, 0, @@ -2534,7 +2581,6 @@ static struct encryption_type enctype_null = { static struct encryption_type enctype_des_cbc_crc = { ETYPE_DES_CBC_CRC, "des-cbc-crc", - NULL, 8, 8, 8, @@ -2549,7 +2595,6 @@ static struct encryption_type enctype_des_cbc_crc = { static struct encryption_type enctype_des_cbc_md4 = { ETYPE_DES_CBC_MD4, "des-cbc-md4", - NULL, 8, 8, 8, @@ -2564,7 +2609,6 @@ static struct encryption_type enctype_des_cbc_md4 = { static struct encryption_type enctype_des_cbc_md5 = { ETYPE_DES_CBC_MD5, "des-cbc-md5", - NULL, 8, 8, 8, @@ -2579,7 +2623,6 @@ static struct encryption_type enctype_des_cbc_md5 = { static struct encryption_type enctype_arcfour_hmac_md5 = { ETYPE_ARCFOUR_HMAC_MD5, "arcfour-hmac-md5", - NULL, 1, 1, 8, @@ -2594,7 +2637,6 @@ static struct encryption_type enctype_arcfour_hmac_md5 = { static struct encryption_type enctype_des3_cbc_md5 = { ETYPE_DES3_CBC_MD5, "des3-cbc-md5", - NULL, 8, 8, 8, @@ -2609,7 +2651,6 @@ static struct encryption_type enctype_des3_cbc_md5 = { static struct encryption_type enctype_des3_cbc_sha1 = { ETYPE_DES3_CBC_SHA1, "des3-cbc-sha1", - NULL, 8, 8, 8, @@ -2624,7 +2665,6 @@ static struct encryption_type enctype_des3_cbc_sha1 = { static struct encryption_type enctype_old_des3_cbc_sha1 = { ETYPE_OLD_DES3_CBC_SHA1, "old-des3-cbc-sha1", - NULL, 8, 8, 8, @@ -2639,7 +2679,6 @@ static struct encryption_type enctype_old_des3_cbc_sha1 = { static struct encryption_type enctype_aes128_cts_hmac_sha1 = { ETYPE_AES128_CTS_HMAC_SHA1_96, "aes128-cts-hmac-sha1-96", - NULL, 16, 1, 16, @@ -2654,7 +2693,6 @@ static struct encryption_type enctype_aes128_cts_hmac_sha1 = { static struct encryption_type enctype_aes256_cts_hmac_sha1 = { ETYPE_AES256_CTS_HMAC_SHA1_96, "aes256-cts-hmac-sha1-96", - NULL, 16, 1, 16, @@ -2669,7 +2707,6 @@ static struct encryption_type enctype_aes256_cts_hmac_sha1 = { static struct encryption_type enctype_des_cbc_none = { ETYPE_DES_CBC_NONE, "des-cbc-none", - NULL, 8, 8, 0, @@ -2684,7 +2721,6 @@ static struct encryption_type enctype_des_cbc_none = { static struct encryption_type enctype_des_cfb64_none = { ETYPE_DES_CFB64_NONE, "des-cfb64-none", - NULL, 1, 1, 0, @@ -2699,7 +2735,6 @@ static struct encryption_type enctype_des_cfb64_none = { static struct encryption_type enctype_des_pcbc_none = { ETYPE_DES_PCBC_NONE, "des-pcbc-none", - NULL, 8, 8, 0, @@ -2714,7 +2749,6 @@ static struct encryption_type enctype_des_pcbc_none = { static struct encryption_type enctype_des3_cbc_none = { ETYPE_DES3_CBC_NONE, "des3-cbc-none", - NULL, 8, 8, 0, @@ -2766,14 +2800,15 @@ krb5_enctype_to_string(krb5_context context, struct encryption_type *e; e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); *string = NULL; return KRB5_PROG_ETYPE_NOSUPP; } *string = strdup(e->name); if(*string == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -2790,43 +2825,9 @@ krb5_string_to_enctype(krb5_context context, *etype = etypes[i]->type; return 0; } - krb5_set_error_string (context, "encryption type %s not supported", - string); - return KRB5_PROG_ETYPE_NOSUPP; -} - -krb5_error_code KRB5_LIB_FUNCTION -_krb5_enctype_to_oid(krb5_context context, - krb5_enctype etype, - heim_oid *oid) -{ - struct encryption_type *et = _find_enctype(etype); - if(et == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); - return KRB5_PROG_ETYPE_NOSUPP; - } - if(et->oid == NULL) { - krb5_set_error_string (context, "%s have not oid", et->name); - return KRB5_PROG_ETYPE_NOSUPP; - } - krb5_clear_error_string(context); - return der_copy_oid(et->oid, oid); -} - -krb5_error_code KRB5_LIB_FUNCTION -_krb5_oid_to_enctype(krb5_context context, - const heim_oid *oid, - krb5_enctype *etype) -{ - int i; - for(i = 0; i < num_etypes; i++) { - if(etypes[i]->oid && der_heim_oid_cmp(etypes[i]->oid, oid) == 0) { - *etype = etypes[i]->type; - return 0; - } - } - krb5_set_error_string(context, "enctype for oid not supported"); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %s not supported", + string); return KRB5_PROG_ETYPE_NOSUPP; } @@ -2837,7 +2838,8 @@ krb5_enctype_to_keytype(krb5_context context, { struct encryption_type *e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", etype); return KRB5_PROG_ETYPE_NOSUPP; } @@ -2845,21 +2847,6 @@ krb5_enctype_to_keytype(krb5_context context, return 0; } -#if 0 -krb5_error_code KRB5_LIB_FUNCTION -krb5_keytype_to_enctype(krb5_context context, - krb5_keytype keytype, - krb5_enctype *etype) -{ - struct key_type *kt = _find_keytype(keytype); - krb5_warnx(context, "krb5_keytype_to_enctype(%u)", keytype); - if(kt == NULL) - return KRB5_PROG_KEYTYPE_NOSUPP; - *etype = kt->best_etype; - return 0; -} -#endif - krb5_error_code KRB5_LIB_FUNCTION krb5_keytype_to_enctypes (krb5_context context, krb5_keytype keytype, @@ -2877,7 +2864,7 @@ krb5_keytype_to_enctypes (krb5_context context, } ret = malloc(n * sizeof(*ret)); if (ret == NULL && n != 0) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } n = 0; @@ -2902,7 +2889,7 @@ krb5_keytype_to_enctypes_default (krb5_context context, unsigned *len, krb5_enctype **val) { - int i, n; + unsigned int i, n; krb5_enctype *ret; if (keytype != KEYTYPE_DES || context->etypes_des == NULL) @@ -2912,7 +2899,7 @@ krb5_keytype_to_enctypes_default (krb5_context context, ; ret = malloc (n * sizeof(*ret)); if (ret == NULL && n != 0) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for (i = 0; i < n; ++i) @@ -2928,13 +2915,15 @@ krb5_enctype_valid(krb5_context context, { struct encryption_type *e = _find_enctype(etype); if(e == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } if (e->flags & F_DISABLED) { - krb5_set_error_string (context, "encryption type %s is disabled", - e->name); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %s is disabled", + e->name); return KRB5_PROG_ETYPE_NOSUPP; } return 0; @@ -2946,13 +2935,15 @@ krb5_cksumtype_valid(krb5_context context, { struct checksum_type *c = _find_checksum(ctype); if (c == NULL) { - krb5_set_error_string (context, "checksum type %d not supported", - ctype); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %d not supported", + ctype); return KRB5_PROG_SUMTYPE_NOSUPP; } if (c->flags & F_DISABLED) { - krb5_set_error_string (context, "checksum type %s is disabled", - c->name); + krb5_set_error_message (context, KRB5_PROG_SUMTYPE_NOSUPP, + "checksum type %s is disabled", + c->name); return KRB5_PROG_SUMTYPE_NOSUPP; } return 0; @@ -3010,7 +3001,7 @@ encrypt_internal_derived(krb5_context context, total_sz = block_sz + checksum_sz; p = calloc(1, total_sz); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -3077,7 +3068,7 @@ encrypt_internal(krb5_context context, block_sz = (sz + et->padsize - 1) &~ (et->padsize - 1); /* pad */ p = calloc(1, block_sz); if(p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -3142,7 +3133,7 @@ encrypt_internal_special(krb5_context context, tmp = malloc (sz); if (tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p = tmp; @@ -3181,8 +3172,9 @@ decrypt_internal_derived(krb5_context context, checksum_sz = CHECKSUMSIZE(et->keyed_checksum); if (len < checksum_sz + et->confoundersize) { - krb5_set_error_string(context, "Encrypted data shorter then " - "checksum + confunder"); + krb5_set_error_message(context, KRB5_BAD_MSIZE, + "Encrypted data shorter then " + "checksum + confunder"); return KRB5_BAD_MSIZE; } @@ -3193,7 +3185,7 @@ decrypt_internal_derived(krb5_context context, p = malloc(len); if(len != 0 && p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3238,7 +3230,7 @@ decrypt_internal_derived(krb5_context context, result->data = realloc(p, l); if(result->data == NULL && l != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = l; @@ -3267,7 +3259,7 @@ decrypt_internal(krb5_context context, checksum_sz = CHECKSUMSIZE(et->checksum); p = malloc(len); if(len != 0 && p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3303,7 +3295,7 @@ decrypt_internal(krb5_context context, result->data = realloc(p, l); if(result->data == NULL && l != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = l; @@ -3332,7 +3324,7 @@ decrypt_internal_special(krb5_context context, p = malloc (len); if (p == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(p, data, len); @@ -3347,7 +3339,7 @@ decrypt_internal_special(krb5_context context, result->data = realloc(p, sz); if(result->data == NULL && sz != 0) { free(p); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } result->length = sz; @@ -3463,6 +3455,7 @@ seed_something(void) fd = open(seedfile, O_RDONLY); if (fd >= 0) { ssize_t ret; + rk_cloexec(fd); ret = read(fd, buf, sizeof(buf)); if (ret > 0) RAND_add(buf, ret, 0.0); @@ -3547,13 +3540,13 @@ derive_key(krb5_context context, 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"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(constant, len, k, et->blocksize); if (ret) { free(k); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } for(i = 0; i < nblocks; i++) { @@ -3570,7 +3563,7 @@ derive_key(krb5_context context, size_t res_len = (kt->bits + 7) / 8; if(len != 0 && c == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(c, constant, len); @@ -3578,13 +3571,13 @@ derive_key(krb5_context context, k = malloc(res_len); if(res_len != 0 && k == NULL) { free(c); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(c, len, k, res_len); if (ret) { free(k); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } free(c); @@ -3600,10 +3593,10 @@ derive_key(krb5_context context, memcpy(key->key->keyvalue.data, k, key->key->keyvalue.length); break; default: - krb5_set_error_string(context, - "derive_key() called with unknown keytype (%u)", - kt->type); ret = KRB5_CRYPTO_INTERNAL; + krb5_set_error_message(context, ret, + "derive_key() called with unknown keytype (%u)", + kt->type); break; } if (key->schedule) { @@ -3645,8 +3638,9 @@ krb5_derive_key(krb5_context context, et = _find_enctype (etype); if (et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - etype); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } @@ -3679,7 +3673,7 @@ _get_derived_key(krb5_context context, } d = _new_derived_key(crypto, usage); if(d == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_copy_keyblock(context, crypto->key.key, &d->key); @@ -3699,7 +3693,7 @@ krb5_crypto_init(krb5_context context, krb5_error_code ret; ALLOC(*crypto, 1); if(*crypto == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(etype == ETYPE_NULL) @@ -3708,14 +3702,16 @@ krb5_crypto_init(krb5_context context, if((*crypto)->et == NULL || ((*crypto)->et->flags & F_DISABLED)) { free(*crypto); *crypto = NULL; - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } if((*crypto)->et->keytype->size != key->keyvalue.length) { free(*crypto); *crypto = NULL; - krb5_set_error_string (context, "encryption key has bad length"); + krb5_set_error_message (context, KRB5_BAD_KEYSIZE, + "encryption key has bad length"); return KRB5_BAD_KEYSIZE; } ret = krb5_copy_keyblock(context, key, &(*crypto)->key.key); @@ -3803,8 +3799,9 @@ krb5_enctype_disable(krb5_context context, struct encryption_type *et = _find_enctype(enctype); if(et == NULL) { if (context) - krb5_set_error_string (context, "encryption type %d not supported", - enctype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); return KRB5_PROG_ETYPE_NOSUPP; } et->flags |= F_DISABLED; @@ -3825,15 +3822,17 @@ krb5_string_to_key_derived(krb5_context context, u_char *tmp; if(et == NULL) { - krb5_set_error_string (context, "encryption type %d not supported", - etype); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + etype); return KRB5_PROG_ETYPE_NOSUPP; } keylen = et->keytype->bits / 8; ALLOC(kd.key, 1); if(kd.key == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } ret = krb5_data_alloc(&kd.key->keyvalue, et->keytype->size); @@ -3845,13 +3844,13 @@ krb5_string_to_key_derived(krb5_context context, tmp = malloc (keylen); if(tmp == NULL) { krb5_free_keyblock(context, kd.key); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_n_fold(str, len, tmp, keylen); if (ret) { free(tmp); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message (context, ENOMEM, "malloc: out of memory"); return ret; } kd.schedule = NULL; @@ -3970,14 +3969,16 @@ krb5_random_to_key(krb5_context context, krb5_error_code ret; struct encryption_type *et = _find_enctype(type); if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } if ((et->keytype->bits + 7) / 8 > size) { - krb5_set_error_string(context, "encryption key %s needs %d bytes " - "of random to make an encryption key out of it", - et->name, (int)et->keytype->size); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption key %s needs %d bytes " + "of random to make an encryption key out of it", + et->name, (int)et->keytype->size); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_alloc(&key->keyvalue, et->keytype->size); @@ -4009,15 +4010,16 @@ _krb5_pk_octetstring2key(krb5_context context, unsigned char shaoutput[20]; if(et == NULL) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } keylen = (et->keytype->bits + 7) / 8; keydata = malloc(keylen); if (keydata == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -4050,6 +4052,182 @@ _krb5_pk_octetstring2key(krb5_context context, return ret; } +static krb5_error_code +encode_uvinfo(krb5_context context, krb5_const_principal p, krb5_data *data) +{ + KRB5PrincipalName pn; + krb5_error_code ret; + size_t size; + + pn.principalName = p->name; + pn.realm = p->realm; + + ASN1_MALLOC_ENCODE(KRB5PrincipalName, data->data, data->length, + &pn, &size, ret); + if (ret) { + krb5_data_zero(data); + krb5_set_error_message(context, ret, + "Failed to encode KRB5PrincipalName"); + return ret; + } + if (data->length != size) + krb5_abortx(context, "asn1 compiler internal error"); + return 0; +} + +static krb5_error_code +encode_otherinfo(krb5_context context, + const AlgorithmIdentifier *ai, + krb5_const_principal client, + krb5_const_principal server, + krb5_enctype enctype, + const krb5_data *as_req, + const krb5_data *pk_as_rep, + const Ticket *ticket, + krb5_data *other) +{ + PkinitSP80056AOtherInfo otherinfo; + PkinitSuppPubInfo pubinfo; + krb5_error_code ret; + krb5_data pub; + size_t size; + + krb5_data_zero(other); + memset(&otherinfo, 0, sizeof(otherinfo)); + memset(&pubinfo, 0, sizeof(pubinfo)); + + pubinfo.enctype = enctype; + pubinfo.as_REQ = *as_req; + pubinfo.pk_as_rep = *pk_as_rep; + pubinfo.ticket = *ticket; + ASN1_MALLOC_ENCODE(PkinitSuppPubInfo, pub.data, pub.length, + &pubinfo, &size, ret); + if (ret) { + krb5_set_error_message(context, ret, "out of memory"); + return ret; + } + if (pub.length != size) + krb5_abortx(context, "asn1 compiler internal error"); + + ret = encode_uvinfo(context, client, &otherinfo.partyUInfo); + if (ret) { + free(pub.data); + return ret; + } + ret = encode_uvinfo(context, server, &otherinfo.partyVInfo); + if (ret) { + free(otherinfo.partyUInfo.data); + free(pub.data); + return ret; + } + + otherinfo.algorithmID = *ai; + otherinfo.suppPubInfo = &pub; + + ASN1_MALLOC_ENCODE(PkinitSP80056AOtherInfo, other->data, other->length, + &otherinfo, &size, ret); + free(otherinfo.partyUInfo.data); + free(otherinfo.partyVInfo.data); + free(pub.data); + if (ret) { + krb5_set_error_message(context, ret, "out of memory"); + return ret; + } + if (other->length != size) + krb5_abortx(context, "asn1 compiler internal error"); + + return 0; +} + +krb5_error_code +_krb5_pk_kdf(krb5_context context, + const struct AlgorithmIdentifier *ai, + const void *dhdata, + size_t dhsize, + krb5_const_principal client, + krb5_const_principal server, + krb5_enctype enctype, + const krb5_data *as_req, + const krb5_data *pk_as_rep, + const Ticket *ticket, + krb5_keyblock *key) +{ + struct encryption_type *et; + krb5_error_code ret; + krb5_data other; + size_t keylen, offset; + uint32_t counter; + unsigned char *keydata; + unsigned char shaoutput[20]; + + if (der_heim_oid_cmp(oid_id_pkinit_kdf_ah_sha1(), &ai->algorithm) != 0) { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kdf not supported"); + return KRB5_PROG_ETYPE_NOSUPP; + } + if (ai->parameters != NULL && + (ai->parameters->length != 2 || + memcmp(ai->parameters->data, "\x05\x00", 2) != 0)) + { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kdf params not NULL or the NULL-type"); + return KRB5_PROG_ETYPE_NOSUPP; + } + + et = _find_enctype(enctype); + if(et == NULL) { + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + enctype); + return KRB5_PROG_ETYPE_NOSUPP; + } + keylen = (et->keytype->bits + 7) / 8; + + keydata = malloc(keylen); + if (keydata == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + ret = encode_otherinfo(context, ai, client, server, + enctype, as_req, pk_as_rep, ticket, &other); + if (ret) { + free(keydata); + return ret; + } + + offset = 0; + counter = 1; + do { + unsigned char cdata[4]; + SHA_CTX m; + + SHA1_Init(&m); + _krb5_put_int(cdata, counter, 4); + SHA1_Update(&m, cdata, 4); + SHA1_Update(&m, dhdata, dhsize); + SHA1_Update(&m, other.data, other.length); + SHA1_Final(shaoutput, &m); + + memcpy((unsigned char *)keydata + offset, + shaoutput, + min(keylen - offset, sizeof(shaoutput))); + + offset += sizeof(shaoutput); + counter++; + } while(offset < keylen); + memset(shaoutput, 0, sizeof(shaoutput)); + + free(other.data); + + ret = krb5_random_to_key(context, enctype, keydata, keylen, key); + memset(keydata, 0, sizeof(keylen)); + free(keydata); + + return ret; +} + + krb5_error_code KRB5_LIB_FUNCTION krb5_crypto_prf_length(krb5_context context, krb5_enctype type, @@ -4058,8 +4236,9 @@ krb5_crypto_prf_length(krb5_context context, struct encryption_type *et = _find_enctype(type); if(et == NULL || et->prf_length == 0) { - krb5_set_error_string(context, "encryption type %d not supported", - type); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "encryption type %d not supported", + type); return KRB5_PROG_ETYPE_NOSUPP; } @@ -4078,8 +4257,9 @@ krb5_crypto_prf(krb5_context context, krb5_data_zero(output); if(et->prf == NULL) { - krb5_set_error_string(context, "kerberos prf for %s not supported", - et->name); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "kerberos prf for %s not supported", + et->name); return KRB5_PROG_ETYPE_NOSUPP; } diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index eda1a8b259..2b78bfb32b 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: data.c 22064 2007-11-11 16:28:14Z lha $"); +RCSID("$Id: data.c 23280 2008-06-23 03:26:18Z lha $"); /** * Reset the (potentially uninitalized) krb5_data structure. @@ -192,7 +192,7 @@ krb5_copy_data(krb5_context context, krb5_error_code ret; ALLOC(*outdata, 1); if(*outdata == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = der_copy_octet_string(indata, *outdata); diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index ff6e98a3dc..6679b76749 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -33,59 +33,71 @@ #include "krb5_locl.h" -RCSID("$Id: error_string.c 22142 2007-12-04 16:56:02Z lha $"); +RCSID("$Id: error_string.c 23274 2008-06-23 03:25:08Z lha $"); #undef __attribute__ #define __attribute__(X) void KRB5_LIB_FUNCTION -krb5_free_error_string(krb5_context context, char *str) -{ - HEIMDAL_MUTEX_lock(context->mutex); - if (str != context->error_buf) - free(str); - HEIMDAL_MUTEX_unlock(context->mutex); -} - -void KRB5_LIB_FUNCTION krb5_clear_error_string(krb5_context context) { HEIMDAL_MUTEX_lock(context->mutex); - if (context->error_string != NULL - && context->error_string != context->error_buf) + if (context->error_string) free(context->error_string); + context->error_code = 0; context->error_string = NULL; HEIMDAL_MUTEX_unlock(context->mutex); } -krb5_error_code KRB5_LIB_FUNCTION -krb5_set_error_string(krb5_context context, const char *fmt, ...) - __attribute__((format (printf, 2, 3))) +/** + * Set the context full error string for a specific error code. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param ... printf(3) style parameters. + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION +krb5_set_error_message(krb5_context context, krb5_error_code ret, + const char *fmt, ...) + __attribute__ ((format (printf, 3, 4))) { - krb5_error_code ret; va_list ap; va_start(ap, fmt); - ret = krb5_vset_error_string (context, fmt, ap); + krb5_vset_error_message (context, ret, fmt, ap); va_end(ap); - return ret; } -krb5_error_code KRB5_LIB_FUNCTION -krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) - __attribute__ ((format (printf, 2, 0))) +/** + * Set the context full error string for a specific error code. + * + * @param context Kerberos 5 context + * @param ret The error code + * @param fmt Error string for the error code + * @param args printf(3) style parameters. + * + * @ingroup krb5_error + */ + + +void KRB5_LIB_FUNCTION +krb5_vset_error_message (krb5_context context, krb5_error_code ret, + const char *fmt, va_list args) + __attribute__ ((format (printf, 3, 0))) { + krb5_clear_error_string(context); HEIMDAL_MUTEX_lock(context->mutex); + context->error_code = ret; vasprintf(&context->error_string, fmt, args); - if(context->error_string == NULL) { - vsnprintf (context->error_buf, sizeof(context->error_buf), fmt, args); - context->error_string = context->error_buf; - } HEIMDAL_MUTEX_unlock(context->mutex); - return 0; } + /** * Return the error message in context. On error or no error string, * the function returns NULL. @@ -93,7 +105,7 @@ krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) * @param context Kerberos 5 context * * @return an error string, needs to be freed with - * krb5_free_error_string(). The functions return NULL on error. + * krb5_free_error_message(). The functions return NULL on error. * * @ingroup krb5_error */ @@ -121,35 +133,99 @@ krb5_have_error_string(krb5_context context) } /** - * Return the error message for `code' in context. On error the - * function returns NULL. + * Return the error message for `code' in context. On memory + * allocation 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. + * krb5_free_error_message(). The functions return NULL on error. * * @ingroup krb5_error */ -char * KRB5_LIB_FUNCTION +const char * KRB5_LIB_FUNCTION krb5_get_error_message(krb5_context context, krb5_error_code code) { const char *cstr; char *str; - str = krb5_get_error_string(context); - if (str) - return str; + HEIMDAL_MUTEX_lock(context->mutex); + if (context->error_string && + (code == context->error_code || context->error_code == 0)) + { + str = strdup(context->error_string); + if (str) { + HEIMDAL_MUTEX_unlock(context->mutex); + return str; + } + } + HEIMDAL_MUTEX_unlock(context->mutex); cstr = krb5_get_err_text(context, code); if (cstr) return strdup(cstr); - if (asprintf(&str, "<unknown error: %d>", code) == -1) + if (asprintf(&str, "<unknown error: %d>", (int)code) == -1) return NULL; return str; } + +/** + * Free the error message returned by krb5_get_error_message(). + * + * @param context Kerberos context + * @param msg error message to free, returned byg + * krb5_get_error_message(). + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION +krb5_free_error_message(krb5_context context, const char *msg) +{ + free(rk_UNCONST(msg)); +} + +#ifndef HEIMDAL_SMALLER + +/** + * Free the error message returned by krb5_get_error_string(), + * deprecated, use krb5_free_error_message(). + * + * @param context Kerberos context + * @param msg error message to free + * + * @ingroup krb5_error + */ + +void KRB5_LIB_FUNCTION __attribute__((deprecated)) +krb5_free_error_string(krb5_context context, char *str) +{ + krb5_free_error_message(context, str); +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_error_string(krb5_context context, const char *fmt, ...) + __attribute__((format (printf, 2, 3))) __attribute__((deprecated)) +{ + va_list ap; + + va_start(ap, fmt); + krb5_vset_error_message (context, 0, fmt, ap); + va_end(ap); + return 0; +} + +krb5_error_code KRB5_LIB_FUNCTION +krb5_vset_error_string(krb5_context context, const char *fmt, va_list args) + __attribute__ ((format (printf, 2, 0))) __attribute__((deprecated)) +{ + krb5_vset_error_message(context, 0, fmt, args); + return 0; +} + +#endif /* !HEIMDAL_SMALLER */ diff --git a/source4/heimdal/lib/krb5/expand_hostname.c b/source4/heimdal/lib/krb5/expand_hostname.c index 28e39afb42..d06d576432 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 22229 2007-12-08 21:40:59Z lha $"); +RCSID("$Id: expand_hostname.c 23280 2008-06-23 03:26:18Z lha $"); static krb5_error_code copy_hostname(krb5_context context, @@ -42,7 +42,7 @@ copy_hostname(krb5_context context, { *new_hostname = strdup (orig_hostname); if (*new_hostname == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlwr (*new_hostname); @@ -76,7 +76,8 @@ krb5_expand_hostname (krb5_context context, *new_hostname = strdup (a->ai_canonname); freeaddrinfo (ai); if (*new_hostname == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, + "malloc: out of memory"); return ENOMEM; } else { return 0; diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index 484df059ab..8951bdb24e 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: fcache.c 22517 2008-01-24 11:45:51Z lha $"); +RCSID("$Id: fcache.c 23444 2008-07-27 12:07:47Z lha $"); typedef struct krb5_fcache{ char *filename; @@ -93,12 +93,12 @@ _krb5_xlock(krb5_context context, int fd, krb5_boolean exclusive, ret = 0; break; case EAGAIN: - krb5_set_error_string(context, "timed out locking cache file %s", - filename); + krb5_set_error_message(context, ret, "timed out locking cache file %s", + filename); break; default: - krb5_set_error_string(context, "error locking cache file %s: %s", - filename, strerror(ret)); + krb5_set_error_message(context, ret, "error locking cache file %s: %s", + filename, strerror(ret)); break; } return ret; @@ -127,14 +127,40 @@ _krb5_xunlock(krb5_context context, int fd) ret = 0; break; default: - krb5_set_error_string(context, - "Failed to unlock file: %s", strerror(ret)); + krb5_set_error_message(context, ret, + "Failed to unlock file: %s", + strerror(ret)); break; } return ret; } static krb5_error_code +write_storage(krb5_context context, krb5_storage *sp, int fd) +{ + krb5_error_code ret; + krb5_data data; + ssize_t sret; + + ret = krb5_storage_to_data(sp, &data); + if (ret) { + krb5_set_error_message(context, ret, "malloc: out of memory"); + return ret; + } + sret = write(fd, data.data, data.length); + ret = (sret != data.length); + krb5_data_free(&data); + if (ret) { + ret = errno; + krb5_set_error_message(context, ret, + "Failed to write FILE credential data"); + return ret; + } + return 0; +} + + +static krb5_error_code fcc_lock(krb5_context context, krb5_ccache id, int fd, krb5_boolean exclusive) { @@ -153,13 +179,15 @@ fcc_resolve(krb5_context context, krb5_ccache *id, const char *res) krb5_fcache *f; f = malloc(sizeof(*f)); if(f == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } f->filename = strdup(res); if(f->filename == NULL){ free(f); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } f->version = 0; @@ -203,7 +231,7 @@ scrub_file (int fd) */ static krb5_error_code -erase_file(const char *filename) +erase_file(krb5_context context, const char *filename) { int fd; struct stat sb1, sb2; @@ -220,12 +248,20 @@ erase_file(const char *filename) else return errno; } + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, filename); + if (ret) { + close(fd); + return ret; + } if (unlink(filename) < 0) { + _krb5_xunlock(context, fd); close (fd); return errno; } ret = fstat (fd, &sb2); if (ret < 0) { + _krb5_xunlock(context, fd); close (fd); return errno; } @@ -233,6 +269,7 @@ erase_file(const char *filename) /* check if someone was playing with symlinks */ if (sb1.st_dev != sb2.st_dev || sb1.st_ino != sb2.st_ino) { + _krb5_xunlock(context, fd); close (fd); return EPERM; } @@ -240,11 +277,18 @@ erase_file(const char *filename) /* there are still hard links to this file */ if (sb2.st_nlink != 0) { + _krb5_xunlock(context, fd); close (fd); return 0; } ret = scrub_file (fd); + if (ret) { + _krb5_xunlock(context, fd); + close(fd); + return ret; + } + ret = _krb5_xunlock(context, fd); close (fd); return ret; } @@ -258,19 +302,21 @@ fcc_gen_new(krb5_context context, krb5_ccache *id) f = malloc(sizeof(*f)); if(f == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); if(file == NULL) { free(f); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, + "malloc: out of memory"); return KRB5_CC_NOMEM; } fd = mkstemp(file); if(fd < 0) { int ret = errno; - krb5_set_error_string(context, "mkstemp %s", file); + krb5_set_error_message(context, ret, "mkstemp %s", file); free(f); free(file); return ret; @@ -323,11 +369,12 @@ fcc_open(krb5_context context, fd = open(filename, flags, mode); if(fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", filename, + strerror(ret)); return ret; } - + rk_cloexec(fd); + if((ret = fcc_lock(context, id, fd, exclusive)) != 0) { close(fd); return ret; @@ -353,7 +400,7 @@ fcc_initialize(krb5_context context, return ret; { krb5_storage *sp; - sp = krb5_storage_from_fd(fd); + sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); if(context->fcache_vno != 0) f->version = context->fcache_vno; @@ -376,14 +423,16 @@ fcc_initialize(krb5_context context, } ret |= krb5_store_principal(sp, primary_principal); + ret |= write_storage(context, sp, fd); + krb5_storage_free(sp); } fcc_unlock(context, fd); if (close(fd) < 0) if (ret == 0) { ret = errno; - krb5_set_error_string (context, "close %s: %s", - FILENAME(id), strerror(ret)); + krb5_set_error_message (context, ret, "close %s: %s", + FILENAME(id), strerror(ret)); } return ret; } @@ -401,7 +450,7 @@ static krb5_error_code fcc_destroy(krb5_context context, krb5_ccache id) { - erase_file(FILENAME(id)); + erase_file(context, FILENAME(id)); return 0; } @@ -418,7 +467,8 @@ fcc_store_cred(krb5_context context, return ret; { krb5_storage *sp; - sp = krb5_storage_from_fd(fd); + + sp = krb5_storage_emem(); krb5_storage_set_eof_code(sp, KRB5_CC_END); storage_set_flags(context, sp, FCACHE(id)->version); if (!krb5_config_get_bool_default(context, NULL, TRUE, @@ -427,15 +477,18 @@ fcc_store_cred(krb5_context context, NULL)) krb5_storage_set_flags(sp, KRB5_STORAGE_CREDS_FLAGS_WRONG_BITORDER); ret = krb5_store_creds(sp, creds); + if (ret == 0) + ret = write_storage(context, sp, fd); krb5_storage_free(sp); } fcc_unlock(context, fd); - if (close(fd) < 0) + if (close(fd) < 0) { if (ret == 0) { ret = errno; - krb5_set_error_string (context, "close %s: %s", - FILENAME(id), strerror(ret)); + krb5_set_error_message (context, ret, "close %s: %s", + FILENAME(id), strerror(ret)); } + } return ret; } @@ -464,25 +517,27 @@ init_fcc (krb5_context context, ret = krb5_ret_int8(sp, &pvno); if(ret != 0) { if(ret == KRB5_CC_END) { - krb5_set_error_string(context, "Empty credential cache file: %s", - FILENAME(id)); ret = ENOENT; + krb5_set_error_message(context, ret, + "Empty credential cache file: %s", + FILENAME(id)); } else - krb5_set_error_string(context, "Error reading pvno in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, "Error reading pvno in " + "cache file: %s", FILENAME(id)); goto out; } if(pvno != 5) { - krb5_set_error_string(context, "Bad version number in credential " - "cache file: %s", FILENAME(id)); ret = KRB5_CCACHE_BADVNO; + krb5_set_error_message(context, ret, "Bad version number in " + "credential cache file: %s", + FILENAME(id)); goto out; } ret = krb5_ret_int8(sp, &tag); /* should not be host byte order */ if(ret != 0) { - krb5_set_error_string(context, "Error reading tag in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading tag in " + "cache file: %s", FILENAME(id)); goto out; } FCACHE(id)->version = tag; @@ -494,8 +549,9 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &length); if(ret) { ret = KRB5_CC_FORMAT; - krb5_set_error_string(context, "Error reading tag length in " - "cache file: %s", FILENAME(id)); + krb5_set_error_message(context, ret, + "Error reading tag length in " + "cache file: %s", FILENAME(id)); goto out; } while(length > 0) { @@ -505,32 +561,32 @@ init_fcc (krb5_context context, ret = krb5_ret_int16 (sp, &dtag); if(ret) { - krb5_set_error_string(context, "Error reading dtag in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading dtag in " + "cache file: %s", FILENAME(id)); goto out; } ret = krb5_ret_int16 (sp, &data_len); if(ret) { - krb5_set_error_string(context, "Error reading dlength in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading dlength in " + "cache file: %s", FILENAME(id)); goto out; } switch (dtag) { case FCC_TAG_DELTATIME : ret = krb5_ret_int32 (sp, &context->kdc_sec_offset); if(ret) { - krb5_set_error_string(context, "Error reading kdc_sec in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading kdc_sec in " + "cache file: %s", FILENAME(id)); goto out; } ret = krb5_ret_int32 (sp, &context->kdc_usec_offset); if(ret) { - krb5_set_error_string(context, "Error reading kdc_usec in " - "cache file: %s", FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, "Error reading kdc_usec in " + "cache file: %s", FILENAME(id)); goto out; } break; @@ -538,10 +594,11 @@ init_fcc (krb5_context context, for (i = 0; i < data_len; ++i) { ret = krb5_ret_int8 (sp, &dummy); if(ret) { - krb5_set_error_string(context, "Error reading unknown " - "tag in cache file: %s", - FILENAME(id)); ret = KRB5_CC_FORMAT; + krb5_set_error_message(context, ret, + "Error reading unknown " + "tag in cache file: %s", + FILENAME(id)); goto out; } } @@ -557,9 +614,9 @@ init_fcc (krb5_context context, break; default : ret = KRB5_CCACHE_BADVNO; - krb5_set_error_string(context, "Unknown version number (%d) in " - "credential cache file: %s", - (int)tag, FILENAME(id)); + krb5_set_error_message(context, ret, "Unknown version number (%d) in " + "credential cache file: %s", + (int)tag, FILENAME(id)); goto out; } *ret_sp = sp; @@ -610,7 +667,7 @@ fcc_get_first (krb5_context context, *cursor = malloc(sizeof(struct fcc_cursor)); if (*cursor == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memset(*cursor, 0, sizeof(struct fcc_cursor)); @@ -670,7 +727,7 @@ fcc_remove_cred(krb5_context context, krb5_creds *cred) { krb5_error_code ret; - krb5_ccache copy; + krb5_ccache copy, newfile; ret = krb5_cc_gen_new(context, &krb5_mcc_ops, ©); if (ret) @@ -688,12 +745,20 @@ fcc_remove_cred(krb5_context context, return ret; } - fcc_destroy(context, id); + ret = krb5_cc_gen_new(context, &krb5_fcc_ops, &newfile); + if (ret) { + krb5_cc_destroy(context, copy); + return ret; + } - ret = krb5_cc_copy_cache(context, copy, id); + ret = krb5_cc_copy_cache(context, copy, newfile); krb5_cc_destroy(context, copy); + if (ret) { + krb5_cc_destroy(context, newfile); + return ret; + } - return ret; + return krb5_cc_move(context, newfile, id); } static krb5_error_code @@ -704,7 +769,7 @@ fcc_set_flags(krb5_context context, return 0; /* XXX */ } -static krb5_error_code +static int fcc_get_version(krb5_context context, krb5_ccache id) { @@ -722,7 +787,7 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } iter->first = 1; @@ -775,10 +840,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) 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)); + krb5_set_error_message(context, ret, + "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 */ @@ -801,21 +866,19 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) 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"); + krb5_set_error_message(context, ret, + "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"); + krb5_set_error_message(context, ret, + "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); @@ -824,8 +887,10 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) fcc_unlock(context, fd1); close(fd1); + erase_file(context, FILENAME(from)); + if (ret) { - erase_file(FILENAME(to)); + erase_file(context, FILENAME(to)); return ret; } } @@ -856,7 +921,8 @@ fcc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_fcc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops = { + KRB5_CC_OPS_VERSION, "FILE", fcc_get_name, fcc_resolve, diff --git a/source4/heimdal/lib/krb5/generate_subkey.c b/source4/heimdal/lib/krb5/generate_subkey.c index fb99cbbf3f..fb7efbcd29 100644 --- a/source4/heimdal/lib/krb5/generate_subkey.c +++ b/source4/heimdal/lib/krb5/generate_subkey.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: generate_subkey.c 14455 2005-01-05 02:39:21Z lukeh $"); +RCSID("$Id: generate_subkey.c 23280 2008-06-23 03:26:18Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_generate_subkey(krb5_context context, @@ -53,7 +53,7 @@ krb5_generate_subkey_extended(krb5_context context, ALLOC(*subkey, 1); if (*subkey == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index fc78945c63..268550b229 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -1,39 +1,39 @@ /* - * Copyright (c) 1997 - 2007 Kungliga Tekniska Högskolan - * (Royal Institute of Technology, Stockholm, Sweden). - * All rights reserved. + * Copyright (c) 1997 - 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. * - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. * - * 3. Neither the name of the Institute nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. * - * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. */ #include <krb5_locl.h> -RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $"); +RCSID("$Id: get_cred.c 23280 2008-06-23 03:26:18Z lha $"); /* * Take the `body' and encode it into `padata' using the credentials @@ -41,12 +41,11 @@ RCSID("$Id: get_cred.c 22530 2008-01-27 11:48:16Z lha $"); */ static krb5_error_code -make_pa_tgs_req(krb5_context context, +make_pa_tgs_req(krb5_context context, krb5_auth_context ac, KDC_REQ_BODY *body, PA_DATA *padata, - krb5_creds *creds, - krb5_key_usage usage) + krb5_creds *creds) { u_char *buf; size_t buf_size; @@ -65,8 +64,7 @@ make_pa_tgs_req(krb5_context context, ret = _krb5_mk_req_internal(context, &ac, 0, &in_data, creds, &padata->padata_value, KRB5_KU_TGS_REQ_AUTH_CKSUM, - usage - /* KRB5_KU_TGS_REQ_AUTH */); + KRB5_KU_TGS_REQ_AUTH); out: free (buf); if(ret) @@ -101,7 +99,7 @@ set_auth_data (krb5_context context, ALLOC(req_body->enc_authorization_data, 1); if (req_body->enc_authorization_data == NULL) { free (buf); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_crypto_init(context, key, 0, &crypto); @@ -111,9 +109,9 @@ set_auth_data (krb5_context context, req_body->enc_authorization_data = NULL; return ret; } - krb5_encrypt_EncryptedData(context, + krb5_encrypt_EncryptedData(context, crypto, - KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, + KRB5_KU_TGS_REQ_AUTH_DAT_SUBKEY, /* KRB5_KU_TGS_REQ_AUTH_DAT_SESSION? */ buf, len, @@ -125,7 +123,7 @@ set_auth_data (krb5_context context, req_body->enc_authorization_data = NULL; } return 0; -} +} /* * Create a tgs-req in `t' with `addresses', `flags', `second_ticket' @@ -144,8 +142,7 @@ init_tgs_req (krb5_context context, unsigned nonce, const METHOD_DATA *padata, krb5_keyblock **subkey, - TGS_REQ *t, - krb5_key_usage usage) + TGS_REQ *t) { krb5_error_code ret = 0; @@ -156,14 +153,14 @@ init_tgs_req (krb5_context context, ALLOC_SEQ(&t->req_body.etype, 1); if(t->req_body.etype.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } t->req_body.etype.val[0] = in_creds->session.keytype; } else { - ret = krb5_init_etype(context, - &t->req_body.etype.len, - &t->req_body.etype.val, + ret = krb5_init_etype(context, + &t->req_body.etype.len, + &t->req_body.etype.val, NULL); } if (ret) @@ -176,7 +173,7 @@ init_tgs_req (krb5_context context, ALLOC(t->req_body.sname, 1); if (t->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -192,39 +189,39 @@ init_tgs_req (krb5_context context, ALLOC(t->req_body.till, 1); if(t->req_body.till == NULL){ ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *t->req_body.till = in_creds->times.endtime; - + t->req_body.nonce = nonce; if(second_ticket){ ALLOC(t->req_body.additional_tickets, 1); if (t->req_body.additional_tickets == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ALLOC_SEQ(t->req_body.additional_tickets, 1); if (t->req_body.additional_tickets->val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } - ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); + ret = copy_Ticket(second_ticket, t->req_body.additional_tickets->val); if (ret) goto fail; } ALLOC(t->padata, 1); if (t->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ALLOC_SEQ(t->padata, 1 + padata->len); if (t->padata->val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } { @@ -232,7 +229,7 @@ init_tgs_req (krb5_context context, for (i = 0; i < padata->len; i++) { ret = copy_PA_DATA(&padata->val[i], &t->padata->val[i + 1]); if (ret) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } } @@ -278,10 +275,9 @@ init_tgs_req (krb5_context context, ret = make_pa_tgs_req(context, ac, - &t->req_body, + &t->req_body, &t->padata->val[0], - krbtgt, - usage); + krbtgt); if(ret) { if (key) krb5_free_keyblock (context, key); @@ -315,7 +311,7 @@ _krb5_get_krbtgt(krb5_context context, if (ret) return ret; - ret = krb5_make_principal(context, + ret = krb5_make_principal(context, &tmp_cred.server, realm, KRB5_TGS_NAME, @@ -349,7 +345,7 @@ decrypt_tkt_with_subkey (krb5_context context, krb5_data data; size_t size; krb5_crypto crypto; - + ret = krb5_crypto_init(context, key, 0, &crypto); if (ret) return ret; @@ -373,33 +369,32 @@ decrypt_tkt_with_subkey (krb5_context context, } if (ret) return ret; - + ret = krb5_decode_EncASRepPart(context, data.data, data.length, - &dec_rep->enc_part, + &dec_rep->enc_part, &size); if (ret) ret = krb5_decode_EncTGSRepPart(context, data.data, data.length, - &dec_rep->enc_part, + &dec_rep->enc_part, &size); krb5_data_free (&data); return ret; } static krb5_error_code -get_cred_kdc_usage(krb5_context context, - krb5_ccache id, - krb5_kdc_flags flags, - krb5_addresses *addresses, - krb5_creds *in_creds, - krb5_creds *krbtgt, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds *out_creds, - krb5_key_usage usage) +get_cred_kdc(krb5_context context, + krb5_ccache id, + krb5_kdc_flags flags, + krb5_addresses *addresses, + krb5_creds *in_creds, + krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds *out_creds) { TGS_REQ req; krb5_data enc; @@ -412,7 +407,7 @@ get_cred_kdc_usage(krb5_context context, size_t len; Ticket second_ticket_data; METHOD_DATA padata; - + krb5_data_zero(&resp); krb5_data_zero(&enc); padata.val = NULL; @@ -420,10 +415,10 @@ get_cred_kdc_usage(krb5_context context, krb5_generate_random_block(&nonce, sizeof(nonce)); nonce &= 0xffffffff; - + if(flags.b.enc_tkt_in_skey && second_ticket == NULL){ - ret = decode_Ticket(in_creds->second_ticket.data, - in_creds->second_ticket.length, + ret = decode_Ticket(in_creds->second_ticket.data, + in_creds->second_ticket.length, &second_ticket_data, &len); if(ret) return ret; @@ -460,7 +455,7 @@ get_cred_kdc_usage(krb5_context context, KRB5_KU_OTHER_CKSUM, 0, data.data, - data.length, + data.length, &self.cksum); krb5_crypto_destroy(context, crypto); krb5_data_free(&data); @@ -491,14 +486,13 @@ get_cred_kdc_usage(krb5_context context, krbtgt, nonce, &padata, - &subkey, - &req, - usage); + &subkey, + &req); if (ret) goto out; ASN1_MALLOC_ENCODE(TGS_REQ, enc.data, enc.length, &req, &len, ret); - if (ret) + if (ret) goto out; if(enc.length != len) krb5_abortx(context, "internal error in ASN.1 encoder"); @@ -526,20 +520,26 @@ get_cred_kdc_usage(krb5_context context, goto out; memset(&rep, 0, sizeof(rep)); - if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0){ - ret = krb5_copy_principal(context, - in_creds->client, + if(decode_TGS_REP(resp.data, resp.length, &rep.kdc_rep, &len) == 0) { + unsigned eflags = 0; + + ret = krb5_copy_principal(context, + in_creds->client, &out_creds->client); if(ret) - goto out; - ret = krb5_copy_principal(context, - in_creds->server, + goto out2; + ret = krb5_copy_principal(context, + in_creds->server, &out_creds->server); if(ret) - goto out; + goto out2; /* this should go someplace else */ out_creds->times.endtime = in_creds->times.endtime; + /* XXX should do better testing */ + if (flags.b.constrained_delegation || impersonate_principal) + eflags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; + ret = _krb5_extract_ticket(context, &rep, out_creds, @@ -548,10 +548,10 @@ get_cred_kdc_usage(krb5_context context, KRB5_KU_TGS_REP_ENC_PART_SESSION, &krbtgt->addresses, nonce, - EXTRACT_TICKET_ALLOW_CNAME_MISMATCH| - EXTRACT_TICKET_ALLOW_SERVER_MISMATCH, + eflags, decrypt_tkt_with_subkey, subkey); + out2: krb5_free_kdc_rep(context, &rep); } else if(krb5_rd_error(context, &resp, &error) == 0) { ret = krb5_error_from_rd_error(context, &error, in_creds); @@ -575,52 +575,50 @@ out: free(subkey); } return ret; - + } +/* + * same as above, just get local addresses first if the krbtgt have + * them and the realm is not addressless + */ + static krb5_error_code -get_cred_kdc(krb5_context context, - krb5_ccache id, - krb5_kdc_flags flags, - krb5_addresses *addresses, - krb5_creds *in_creds, - krb5_creds *krbtgt, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds *out_creds) +get_cred_kdc_address(krb5_context context, + krb5_ccache id, + krb5_kdc_flags flags, + krb5_addresses *addrs, + krb5_creds *in_creds, + krb5_creds *krbtgt, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds *out_creds) { krb5_error_code ret; + krb5_addresses addresses = { 0, NULL }; - ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, impersonate_principal, second_ticket, - out_creds, KRB5_KU_TGS_REQ_AUTH); - if (ret == KRB5KRB_AP_ERR_BAD_INTEGRITY) { - krb5_clear_error_string (context); - ret = get_cred_kdc_usage(context, id, flags, addresses, in_creds, - krbtgt, impersonate_principal, second_ticket, - out_creds, KRB5_KU_AP_REQ_AUTH); - } - return ret; -} + /* + * Inherit the address-ness of the krbtgt if the address is not + * specified. + */ -/* same as above, just get local addresses first */ + if (addrs == NULL && krbtgt->addresses.len != 0) { + krb5_boolean noaddr; -static krb5_error_code -get_cred_kdc_la(krb5_context context, krb5_ccache id, krb5_kdc_flags flags, - krb5_creds *in_creds, krb5_creds *krbtgt, - krb5_principal impersonate_principal, Ticket *second_ticket, - krb5_creds *out_creds) -{ - krb5_error_code ret; - krb5_addresses addresses, *addrs = &addresses; - - krb5_get_all_client_addrs(context, &addresses); - /* XXX this sucks. */ - if(addresses.len == 0) - addrs = NULL; - ret = get_cred_kdc(context, id, flags, addrs, - in_creds, krbtgt, impersonate_principal, second_ticket, - out_creds); + krb5_appdefault_boolean(context, NULL, krbtgt->server->realm, + "no-addresses", FALSE, &noaddr); + + if (!noaddr) { + krb5_get_all_client_addrs(context, &addresses); + /* XXX this sucks. */ + addrs = &addresses; + if(addresses.len == 0) + addrs = NULL; + } + } + ret = get_cred_kdc(context, id, flags, addrs, in_creds, + krbtgt, impersonate_principal, + second_ticket, out_creds); krb5_free_addresses(context, &addresses); return ret; } @@ -640,7 +638,7 @@ krb5_get_kdc_cred(krb5_context context, *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = _krb5_get_krbtgt (context, @@ -651,7 +649,7 @@ krb5_get_kdc_cred(krb5_context context, free(*out_creds); return ret; } - ret = get_cred_kdc(context, id, flags, addresses, + ret = get_cred_kdc(context, id, flags, addresses, in_creds, krbtgt, NULL, NULL, *out_creds); krb5_free_creds (context, krbtgt); if(ret) @@ -659,8 +657,8 @@ krb5_get_kdc_cred(krb5_context context, return ret; } -static void -not_found(krb5_context context, krb5_const_principal p) +static int +not_found(krb5_context context, krb5_const_principal p, krb5_error_code code) { krb5_error_code ret; char *str; @@ -668,10 +666,11 @@ not_found(krb5_context context, krb5_const_principal p) ret = krb5_unparse_name(context, p, &str); if(ret) { krb5_clear_error_string(context); - return; + return code; } - krb5_set_error_string(context, "Matching credential (%s) not found", str); + krb5_set_error_message(context, code, "Matching credential (%s) not found", str); free(str); + return code; } static krb5_error_code @@ -686,24 +685,23 @@ find_cred(krb5_context context, krb5_cc_clear_mcred(&mcreds); mcreds.server = server; - ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, + ret = krb5_cc_retrieve_cred(context, id, KRB5_TC_DONT_MATCH_REALM, &mcreds, out_creds); if(ret == 0) return 0; while(tgts && *tgts){ - if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, + if(krb5_compare_creds(context, KRB5_TC_DONT_MATCH_REALM, &mcreds, *tgts)){ ret = krb5_copy_creds_contents(context, *tgts, out_creds); return ret; } tgts++; } - not_found(context, server); - return KRB5_CC_NOTFOUND; + return not_found(context, server, KRB5_CC_NOTFOUND); } static krb5_error_code -add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt) +add_cred(krb5_context context, krb5_creds const *tkt, krb5_creds ***tgts) { int i; krb5_error_code ret; @@ -712,7 +710,7 @@ add_cred(krb5_context context, krb5_creds ***tgts, krb5_creds *tkt) for(i = 0; tmp && tmp[i]; i++); /* XXX */ tmp = realloc(tmp, (i+2)*sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *tgts = tmp; @@ -737,14 +735,14 @@ get_cred(server) */ static krb5_error_code -get_cred_from_kdc_flags(krb5_context context, - krb5_kdc_flags flags, - krb5_ccache ccache, - krb5_creds *in_creds, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds **out_creds, - krb5_creds ***ret_tgts) +get_cred_kdc_capath(krb5_context context, + krb5_kdc_flags flags, + krb5_ccache ccache, + krb5_creds *in_creds, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds **out_creds, + krb5_creds ***ret_tgts) { krb5_error_code ret; krb5_creds *tgt, tmp_creds; @@ -759,7 +757,7 @@ get_cred_from_kdc_flags(krb5_context context, if(ret) return ret; - try_realm = krb5_config_get_string(context, NULL, "capaths", + try_realm = krb5_config_get_string(context, NULL, "capaths", client_realm, server_realm, NULL); if (try_realm == NULL) try_realm = client_realm; @@ -768,7 +766,7 @@ get_cred_from_kdc_flags(krb5_context context, &tmp_creds.server, try_realm, KRB5_TGS_NAME, - server_realm, + server_realm, NULL); if(ret){ krb5_free_principal(context, tmp_creds.client); @@ -776,32 +774,20 @@ get_cred_from_kdc_flags(krb5_context context, } { krb5_creds tgts; - /* XXX try krb5_cc_retrieve_cred first? */ - ret = find_cred(context, ccache, tmp_creds.server, + + ret = find_cred(context, ccache, tmp_creds.server, *ret_tgts, &tgts); if(ret == 0){ *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { - krb5_boolean noaddr; - - krb5_appdefault_boolean(context, NULL, tgts.server->realm, - "no-addresses", FALSE, &noaddr); - - if (noaddr) - ret = get_cred_kdc(context, ccache, flags, NULL, - in_creds, &tgts, - impersonate_principal, - second_ticket, - *out_creds); - else - ret = get_cred_kdc_la(context, ccache, flags, - in_creds, &tgts, - impersonate_principal, - second_ticket, - *out_creds); + ret = get_cred_kdc_address(context, ccache, flags, NULL, + in_creds, &tgts, + impersonate_principal, + second_ticket, + *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -813,22 +799,21 @@ get_cred_from_kdc_flags(krb5_context context, return ret; } } - if(krb5_realm_compare(context, in_creds->client, in_creds->server)) { - not_found(context, in_creds->server); - return KRB5_CC_NOTFOUND; - } + if(krb5_realm_compare(context, in_creds->client, in_creds->server)) + return not_found(context, in_creds->server, KRB5_CC_NOTFOUND); + /* XXX this can loop forever */ while(1){ heim_general_string tgt_inst; - ret = get_cred_from_kdc_flags(context, flags, ccache, &tmp_creds, - NULL, NULL, &tgt, ret_tgts); + ret = get_cred_kdc_capath(context, flags, ccache, &tmp_creds, + NULL, NULL, &tgt, ret_tgts); if(ret) { krb5_free_principal(context, tmp_creds.server); krb5_free_principal(context, tmp_creds.client); return ret; } - ret = add_cred(context, ret_tgts, tgt); + ret = add_cred(context, tgt, ret_tgts); if(ret) { krb5_free_principal(context, tmp_creds.server); krb5_free_principal(context, tmp_creds.client); @@ -838,7 +823,7 @@ get_cred_from_kdc_flags(krb5_context context, if(strcmp(tgt_inst, server_realm) == 0) break; krb5_free_principal(context, tmp_creds.server); - ret = krb5_make_principal(context, &tmp_creds.server, + ret = krb5_make_principal(context, &tmp_creds.server, tgt_inst, KRB5_TGS_NAME, server_realm, NULL); if(ret) { krb5_free_principal(context, tmp_creds.server); @@ -857,22 +842,12 @@ get_cred_from_kdc_flags(krb5_context context, krb5_free_principal(context, tmp_creds.client); *out_creds = calloc(1, sizeof(**out_creds)); if(*out_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); } else { - krb5_boolean noaddr; - - krb5_appdefault_boolean(context, NULL, tgt->server->realm, - "no-addresses", KRB5_ADDRESSLESS_DEFAULT, - &noaddr); - if (noaddr) - ret = get_cred_kdc (context, ccache, flags, NULL, - in_creds, tgt, NULL, NULL, - *out_creds); - else - ret = get_cred_kdc_la(context, ccache, flags, - in_creds, tgt, NULL, NULL, - *out_creds); + ret = get_cred_kdc_address (context, ccache, flags, NULL, + in_creds, tgt, impersonate_principal, + second_ticket, *out_creds); if (ret) { free (*out_creds); *out_creds = NULL; @@ -882,6 +857,185 @@ get_cred_from_kdc_flags(krb5_context context, return ret; } +static krb5_error_code +get_cred_kdc_referral(krb5_context context, + krb5_kdc_flags flags, + krb5_ccache ccache, + krb5_creds *in_creds, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds **out_creds, + krb5_creds ***ret_tgts) +{ + krb5_const_realm client_realm; + krb5_error_code ret; + krb5_creds tgt, referral, ticket; + int loop = 0; + + memset(&tgt, 0, sizeof(tgt)); + memset(&ticket, 0, sizeof(ticket)); + + flags.b.canonicalize = 1; + + *out_creds = NULL; + + client_realm = krb5_principal_get_realm(context, in_creds->client); + + /* find tgt for the clients base realm */ + { + krb5_principal tgtname; + + ret = krb5_make_principal(context, &tgtname, + client_realm, + KRB5_TGS_NAME, + client_realm, + NULL); + if(ret) + return ret; + + ret = find_cred(context, ccache, tgtname, *ret_tgts, &tgt); + krb5_free_principal(context, tgtname); + if (ret) + return ret; + } + + referral = *in_creds; + ret = krb5_copy_principal(context, in_creds->server, &referral.server); + if (ret) { + krb5_free_cred_contents(context, &tgt); + return ret; + } + ret = krb5_principal_set_realm(context, referral.server, client_realm); + if (ret) { + krb5_free_cred_contents(context, &tgt); + krb5_free_principal(context, referral.server); + return ret; + } + + while (loop++ < 17) { + krb5_creds **tickets; + krb5_creds mcreds; + char *referral_realm; + + /* Use cache if we are not doing impersonation or contrainte deleg */ + if (impersonate_principal == NULL || flags.b.constrained_delegation) { + krb5_cc_clear_mcred(&mcreds); + mcreds.server = referral.server; + ret = krb5_cc_retrieve_cred(context, ccache, 0, &mcreds, &ticket); + } else + ret = EINVAL; + + if (ret) { + ret = get_cred_kdc_address (context, ccache, flags, NULL, + &referral, &tgt, impersonate_principal, + second_ticket, &ticket); + if (ret) + goto out; + } + + /* Did we get the right ticket ? */ + if (krb5_principal_compare_any_realm(context, + referral.server, + ticket.server)) + break; + + if (ticket.server->name.name_string.len != 2 && + strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0) + { + krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US, + "Got back an non krbtgt ticket referrals"); + krb5_free_cred_contents(context, &ticket); + return KRB5KRB_AP_ERR_NOT_US; + } + + referral_realm = ticket.server->name.name_string.val[1]; + + /* check that there are no referrals loops */ + tickets = *ret_tgts; + + krb5_cc_clear_mcred(&mcreds); + mcreds.server = ticket.server; + + while(tickets && *tickets){ + if(krb5_compare_creds(context, + KRB5_TC_DONT_MATCH_REALM, + &mcreds, + *tickets)) + { + krb5_set_error_message(context, KRB5_GET_IN_TKT_LOOP, + "Referral from %s loops back to realm %s", + tgt.server->realm, + referral_realm); + krb5_free_cred_contents(context, &ticket); + return KRB5_GET_IN_TKT_LOOP; + } + tickets++; + } + + ret = add_cred(context, &ticket, ret_tgts); + if (ret) { + krb5_free_cred_contents(context, &ticket); + goto out; + } + + /* try realm in the referral */ + ret = krb5_principal_set_realm(context, + referral.server, + referral_realm); + krb5_free_cred_contents(context, &tgt); + tgt = ticket; + memset(&ticket, 0, sizeof(ticket)); + if (ret) + goto out; + } + + ret = krb5_copy_creds(context, &ticket, out_creds); + +out: + krb5_free_principal(context, referral.server); + krb5_free_cred_contents(context, &tgt); + return ret; +} + + +/* + * Glue function between referrals version and old client chasing + * codebase. + */ + +static krb5_error_code +get_cred_kdc_any(krb5_context context, + krb5_kdc_flags flags, + krb5_ccache ccache, + krb5_creds *in_creds, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds **out_creds, + krb5_creds ***ret_tgts) +{ + krb5_error_code ret; + + ret = get_cred_kdc_referral(context, + flags, + ccache, + in_creds, + impersonate_principal, + second_ticket, + out_creds, + ret_tgts); + if (ret == 0 || flags.b.canonicalize) + return ret; + return get_cred_kdc_capath(context, + flags, + ccache, + in_creds, + impersonate_principal, + second_ticket, + out_creds, + ret_tgts); +} + + krb5_error_code KRB5_LIB_FUNCTION krb5_get_cred_from_kdc_opt(krb5_context context, krb5_ccache ccache, @@ -892,9 +1046,9 @@ krb5_get_cred_from_kdc_opt(krb5_context context, { krb5_kdc_flags f; f.i = flags; - return get_cred_from_kdc_flags(context, f, ccache, - in_creds, NULL, NULL, - out_creds, ret_tgts); + return get_cred_kdc_any(context, f, ccache, + in_creds, NULL, NULL, + out_creds, ret_tgts); } krb5_error_code KRB5_LIB_FUNCTION @@ -904,10 +1058,10 @@ krb5_get_cred_from_kdc(krb5_context context, krb5_creds **out_creds, krb5_creds ***ret_tgts) { - return krb5_get_cred_from_kdc_opt(context, ccache, + return krb5_get_cred_from_kdc_opt(context, ccache, in_creds, out_creds, ret_tgts, 0); } - + krb5_error_code KRB5_LIB_FUNCTION krb5_get_credentials_with_flags(krb5_context context, @@ -921,18 +1075,18 @@ krb5_get_credentials_with_flags(krb5_context context, krb5_creds **tgts; krb5_creds *res_creds; int i; - + *out_creds = NULL; res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (in_creds->session.keytype) options |= KRB5_TC_MATCH_KEYTYPE; - /* + /* * If we got a credential, check if credential is expired before * returning it. */ @@ -941,7 +1095,7 @@ krb5_get_credentials_with_flags(krb5_context context, in_creds->session.keytype ? KRB5_TC_MATCH_KEYTYPE : 0, in_creds, res_creds); - /* + /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ @@ -953,7 +1107,7 @@ krb5_get_credentials_with_flags(krb5_context context, *out_creds = res_creds; return 0; } - + krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; @@ -967,18 +1121,17 @@ krb5_get_credentials_with_flags(krb5_context context, return ret; } free(res_creds); - if(options & KRB5_GC_CACHED) { - not_found(context, in_creds->server); - return KRB5_CC_NOTFOUND; - } + if(options & KRB5_GC_CACHED) + return not_found(context, in_creds->server, KRB5_CC_NOTFOUND); + if(options & KRB5_GC_USER_USER) flags.b.enc_tkt_in_skey = 1; if (flags.b.enc_tkt_in_skey) options |= KRB5_GC_NO_STORE; tgts = NULL; - ret = get_cred_from_kdc_flags(context, flags, ccache, - in_creds, NULL, NULL, out_creds, &tgts); + ret = get_cred_kdc_any(context, flags, ccache, + in_creds, NULL, NULL, out_creds, &tgts); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); krb5_free_creds(context, tgts[i]); @@ -1015,7 +1168,7 @@ krb5_get_creds_opt_alloc(krb5_context context, krb5_get_creds_opt *opt) { *opt = calloc(1, sizeof(**opt)); if (*opt == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -1079,14 +1232,14 @@ krb5_get_creds_opt_set_ticket(krb5_context context, opt->ticket = malloc(sizeof(*ticket)); if (opt->ticket == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_Ticket(ticket, opt->ticket); if (ret) { free(opt->ticket); opt->ticket = NULL; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } } @@ -1109,7 +1262,7 @@ krb5_get_creds(krb5_context context, krb5_creds **tgts; krb5_creds *res_creds; int i; - + memset(&in_creds, 0, sizeof(in_creds)); in_creds.server = rk_UNCONST(inprinc); @@ -1124,7 +1277,7 @@ krb5_get_creds(krb5_context context, res_creds = calloc(1, sizeof(*res_creds)); if (res_creds == NULL) { krb5_free_principal(context, in_creds.client); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1133,7 +1286,7 @@ krb5_get_creds(krb5_context context, options |= KRB5_TC_MATCH_KEYTYPE; } - /* + /* * If we got a credential, check if credential is expired before * returning it. */ @@ -1141,7 +1294,7 @@ krb5_get_creds(krb5_context context, ccache, opt->enctype ? KRB5_TC_MATCH_KEYTYPE : 0, &in_creds, res_creds); - /* + /* * If we got a credential, check if credential is expired before * returning it, but only if KRB5_GC_EXPIRED_OK is not set. */ @@ -1154,7 +1307,7 @@ krb5_get_creds(krb5_context context, krb5_free_principal(context, in_creds.client); return 0; } - + krb5_timeofday(context, &timeret); if(res_creds->times.endtime > timeret) { *out_creds = res_creds; @@ -1171,9 +1324,8 @@ krb5_get_creds(krb5_context context, } free(res_creds); if(options & KRB5_GC_CACHED) { - not_found(context, in_creds.server); krb5_free_principal(context, in_creds.client); - return KRB5_CC_NOTFOUND; + return not_found(context, in_creds.server, KRB5_CC_NOTFOUND); } if(options & KRB5_GC_USER_USER) { flags.b.enc_tkt_in_skey = 1; @@ -1187,11 +1339,13 @@ krb5_get_creds(krb5_context context, flags.b.request_anonymous = 1; /* XXX ARGH confusion */ flags.b.constrained_delegation = 1; } + if (options & KRB5_GC_CANONICALIZE) + flags.b.canonicalize = 1; tgts = NULL; - ret = get_cred_from_kdc_flags(context, flags, ccache, - &in_creds, opt->self, opt->ticket, - out_creds, &tgts); + ret = get_cred_kdc_any(context, flags, ccache, + &in_creds, opt->self, opt->ticket, + out_creds, &tgts); krb5_free_principal(context, in_creds.client); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); diff --git a/source4/heimdal/lib/krb5/get_default_principal.c b/source4/heimdal/lib/krb5/get_default_principal.c index 83fb2b0fa9..5a7a7829fc 100644 --- a/source4/heimdal/lib/krb5/get_default_principal.c +++ b/source4/heimdal/lib/krb5/get_default_principal.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_principal.c 14870 2005-04-20 20:53:29Z lha $"); +RCSID("$Id: get_default_principal.c 23280 2008-06-23 03:26:18Z lha $"); /* * Try to find out what's a reasonable default principal. @@ -85,8 +85,8 @@ _krb5_get_default_principal_local (krb5_context context, user = getlogin(); } if(user == NULL) { - krb5_set_error_string(context, - "unable to figure out current principal"); + krb5_set_error_message(context, ENOTTY, + "unable to figure out current principal"); return ENOTTY; /* XXX */ } ret = krb5_make_principal(context, princ, NULL, user, NULL); diff --git a/source4/heimdal/lib/krb5/get_default_realm.c b/source4/heimdal/lib/krb5/get_default_realm.c index 09c8577b26..1c996031e8 100644 --- a/source4/heimdal/lib/krb5/get_default_realm.c +++ b/source4/heimdal/lib/krb5/get_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: get_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: get_default_realm.c 23280 2008-06-23 03:26:18Z lha $"); /* * Return a NULL-terminated list of default realms in `realms'. @@ -76,7 +76,7 @@ krb5_get_default_realm(krb5_context context, res = strdup (context->default_realms[0]); if (res == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realm = res; diff --git a/source4/heimdal/lib/krb5/get_for_creds.c b/source4/heimdal/lib/krb5/get_for_creds.c index cb8b7c8641..a8aac950ec 100644 --- a/source4/heimdal/lib/krb5/get_for_creds.c +++ b/source4/heimdal/lib/krb5/get_for_creds.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: get_for_creds.c 22504 2008-01-21 15:49:58Z lha $"); +RCSID("$Id: get_for_creds.c 23316 2008-06-23 04:32:32Z lha $"); static krb5_error_code add_addrs(krb5_context context, @@ -51,8 +51,8 @@ add_addrs(krb5_context context, tmp = realloc(addr->val, (addr->len + n) * sizeof(*addr->val)); if (tmp == NULL && (addr->len + n) != 0) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } addr->val = tmp; @@ -207,7 +207,6 @@ krb5_get_forwarded_creds (krb5_context context, krb5_kdc_flags kdc_flags; krb5_crypto crypto; struct addrinfo *ai; - int save_errno; krb5_creds *ticket; paddrs = NULL; @@ -238,10 +237,10 @@ krb5_get_forwarded_creds (krb5_context context, ret = getaddrinfo (hostname, NULL, NULL, &ai); if (ret) { - save_errno = errno; - krb5_set_error_string(context, "resolving %s: %s", + krb5_error_code ret2 = krb5_eai_to_heim_errno(ret, errno); + krb5_set_error_message(context, ret2, "resolving %s: %s", hostname, gai_strerror(ret)); - return krb5_eai_to_heim_errno(ret, save_errno); + return ret2; } ret = add_addrs (context, &addrs, ai); @@ -269,7 +268,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC_SEQ(&cred.tickets, 1); if (cred.tickets.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out2; } ret = decode_Ticket(out_creds->ticket.data, @@ -282,7 +281,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC_SEQ(&enc_krb_cred_part.ticket_info, 1); if (enc_krb_cred_part.ticket_info.val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } @@ -295,14 +294,14 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC(enc_krb_cred_part.timestamp, 1); if (enc_krb_cred_part.timestamp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } *enc_krb_cred_part.timestamp = sec; ALLOC(enc_krb_cred_part.usec, 1); if (enc_krb_cred_part.usec == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } *enc_krb_cred_part.usec = usec; @@ -346,7 +345,7 @@ krb5_get_forwarded_creds (krb5_context context, ALLOC(enc_krb_cred_part.r_address, 1); if (enc_krb_cred_part.r_address == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out4; } diff --git a/source4/heimdal/lib/krb5/get_host_realm.c b/source4/heimdal/lib/krb5/get_host_realm.c index d709e4b38d..f4c875b347 100644 --- a/source4/heimdal/lib/krb5/get_host_realm.c +++ b/source4/heimdal/lib/krb5/get_host_realm.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <resolve.h> -RCSID("$Id: get_host_realm.c 18541 2006-10-17 19:28:36Z lha $"); +RCSID("$Id: get_host_realm.c 23316 2008-06-23 04:32:32Z lha $"); /* To automagically find the correct realm of a host (without * [domain_realm] in krb5.conf) add a text record for your domain with @@ -55,7 +55,7 @@ copy_txt_to_realms (struct resource_record *head, krb5_realm **realms) { struct resource_record *rr; - int n, i; + unsigned int n, i; for(n = 0, rr = head; rr; rr = rr->next) if (rr->type == T_TXT) @@ -192,21 +192,22 @@ _krb5_get_host_realm_int (krb5_context context, p++; *realms = malloc(2 * sizeof(krb5_realm)); if (*realms == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*realms)[0] = strdup(p); if((*realms)[0] == NULL) { free(*realms); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strupr((*realms)[0]); (*realms)[1] = NULL; return 0; } - krb5_set_error_string(context, "unable to find realm of host %s", host); + krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN, + "unable to find realm of host %s", host); return KRB5_ERR_HOST_REALM_UNKNOWN; } @@ -248,8 +249,9 @@ krb5_get_host_realm(krb5_context context, */ ret = krb5_get_default_realms(context, realms); if (ret) { - krb5_set_error_string(context, "Unable to find realm of host %s", - host); + krb5_set_error_message(context, KRB5_ERR_HOST_REALM_UNKNOWN, + "Unable to find realm of host %s", + host); return KRB5_ERR_HOST_REALM_UNKNOWN; } } diff --git a/source4/heimdal/lib/krb5/get_in_tkt.c b/source4/heimdal/lib/krb5/get_in_tkt.c index a9ed3857d0..8bdc8c0eb2 100644 --- a/source4/heimdal/lib/krb5/get_in_tkt.c +++ b/source4/heimdal/lib/krb5/get_in_tkt.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2002 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: get_in_tkt.c 20226 2007-02-16 03:31:50Z lha $"); +RCSID("$Id: get_in_tkt.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_init_etype (krb5_context context, @@ -41,7 +41,7 @@ krb5_init_etype (krb5_context context, krb5_enctype **val, const krb5_enctype *etypes) { - int i; + unsigned int i; krb5_error_code ret; krb5_enctype *tmp = NULL; @@ -60,7 +60,7 @@ krb5_init_etype (krb5_context context, *val = malloc(i * sizeof(**val)); if (i != 0 && *val == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto cleanup; } memmove (*val, @@ -72,6 +72,225 @@ cleanup: return ret; } +static krb5_error_code +check_server_referral(krb5_context context, + krb5_kdc_rep *rep, + unsigned flags, + krb5_const_principal requested, + krb5_const_principal returned, + const krb5_keyblock const * key) +{ + krb5_error_code ret; + PA_ServerReferralData ref; + krb5_crypto session; + EncryptedData ed; + size_t len; + krb5_data data; + PA_DATA *pa; + int i = 0, cmp; + + if (rep->kdc_rep.padata == NULL) + goto noreferral; + + pa = krb5_find_padata(rep->kdc_rep.padata->val, + rep->kdc_rep.padata->len, + KRB5_PADATA_SERVER_REFERRAL, &i); + if (pa == NULL) + goto noreferral; + + memset(&ed, 0, sizeof(ed)); + memset(&ref, 0, sizeof(ref)); + + ret = decode_EncryptedData(pa->padata_value.data, + pa->padata_value.length, + &ed, &len); + if (ret) + return ret; + if (len != pa->padata_value.length) { + free_EncryptedData(&ed); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, "Referral EncryptedData wrong"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + ret = krb5_crypto_init(context, key, 0, &session); + if (ret) { + free_EncryptedData(&ed); + return ret; + } + + ret = krb5_decrypt_EncryptedData(context, session, + KRB5_KU_PA_SERVER_REFERRAL, + &ed, &data); + free_EncryptedData(&ed); + krb5_crypto_destroy(context, session); + if (ret) + return ret; + + ret = decode_PA_ServerReferralData(data.data, data.length, &ref, &len); + if (ret) { + krb5_data_free(&data); + return ret; + } + krb5_data_free(&data); + + if (strcmp(requested->realm, returned->realm) != 0) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "server ref realm mismatch"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (returned->name.name_string.len == 2 && + strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0) + { + const char *realm = returned->name.name_string.val[1]; + + if (ref.referred_realm == NULL + || strcmp(*ref.referred_realm, realm) != 0) + { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "tgt returned with wrong ref"); + return KRB5KRB_AP_ERR_MODIFIED; + } + } else if (krb5_principal_compare(context, returned, requested) == 0) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "req princ no same as returned"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + if (ref.requested_principal_name) { + cmp = _krb5_principal_compare_PrincipalName(context, + requested, + ref.requested_principal_name); + if (!cmp) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "compare requested failed"); + return KRB5KRB_AP_ERR_MODIFIED; + } + } else if (flags & EXTRACT_TICKET_AS_REQ) { + free_PA_ServerReferralData(&ref); + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Requested principal missing on AS-REQ"); + return KRB5KRB_AP_ERR_MODIFIED; + } + + free_PA_ServerReferralData(&ref); + + return ret; +noreferral: + if (krb5_principal_compare(context, requested, returned) == FALSE) { + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Not same server principal returned " + "as requested"); + return KRB5KRB_AP_ERR_MODIFIED; + } + return 0; +} + + +/* + * Verify referral data + */ + + +static krb5_error_code +check_client_referral(krb5_context context, + krb5_kdc_rep *rep, + krb5_const_principal requested, + krb5_const_principal mapped, + krb5_keyblock const * key) +{ + krb5_error_code ret; + PA_ClientCanonicalized canon; + krb5_crypto crypto; + krb5_data data; + PA_DATA *pa; + size_t len; + int i = 0; + + if (rep->kdc_rep.padata == NULL) + goto noreferral; + + pa = krb5_find_padata(rep->kdc_rep.padata->val, + rep->kdc_rep.padata->len, + KRB5_PADATA_CLIENT_CANONICALIZED, &i); + if (pa == NULL) + goto noreferral; + + ret = decode_PA_ClientCanonicalized(pa->padata_value.data, + pa->padata_value.length, + &canon, &len); + if (ret) { + krb5_set_error_message(context, ret, "Failed to decode " + "PA_ClientCanonicalized"); + return ret; + } + + ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, + &canon.names, &len, ret); + if (ret) { + free_PA_ClientCanonicalized(&canon); + return ret; + } + if (data.length != len) + krb5_abortx(context, "internal asn.1 error"); + + ret = krb5_crypto_init(context, key, 0, &crypto); + if (ret) { + free(data.data); + free_PA_ClientCanonicalized(&canon); + return ret; + } + + ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES, + data.data, data.length, + &canon.canon_checksum); + krb5_crypto_destroy(context, crypto); + free(data.data); + if (ret) { + krb5_set_error_message(context, ret, "Failed to verify " + "client canonicalized data"); + free_PA_ClientCanonicalized(&canon); + return ret; + } + + if (!_krb5_principal_compare_PrincipalName(context, + requested, + &canon.names.requested_name)) + { + free_PA_ClientCanonicalized(&canon); + krb5_set_error_message(context, KRB5_PRINC_NOMATCH, + "Requested name doesn't match" + " in client referral"); + return KRB5_PRINC_NOMATCH; + } + if (!_krb5_principal_compare_PrincipalName(context, + mapped, + &canon.names.mapped_name)) + { + free_PA_ClientCanonicalized(&canon); + krb5_set_error_message(context, KRB5_PRINC_NOMATCH, + "Mapped name doesn't match" + " in client referral"); + return KRB5_PRINC_NOMATCH; + } + + return 0; + +noreferral: + if (krb5_principal_compare(context, requested, mapped) == FALSE) { + krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, + "Not same client principal returned " + "as requested"); + return KRB5KRB_AP_ERR_MODIFIED; + } + return 0; +} + + static krb5_error_code decrypt_tkt (krb5_context context, @@ -117,9 +336,9 @@ decrypt_tkt (krb5_context context, } int -_krb5_extract_ticket(krb5_context context, - krb5_kdc_rep *rep, - krb5_creds *creds, +_krb5_extract_ticket(krb5_context context, + krb5_kdc_rep *rep, + krb5_creds *creds, krb5_keyblock *key, krb5_const_pointer keyseed, krb5_key_usage key_usage, @@ -131,83 +350,86 @@ _krb5_extract_ticket(krb5_context context, { krb5_error_code ret; krb5_principal tmp_principal; - int tmp; size_t len; time_t tmp_time; krb5_timestamp sec_now; -/* - * HACK: - * this is really a ugly hack, to support using the Netbios Domain Name - * as realm against windows KDC's, they always return the full realm - * based on the DNS Name. - */ -flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; -flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; + /* decrypt */ + + if (decrypt_proc == NULL) + decrypt_proc = decrypt_tkt; + + ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); + if (ret) + goto out; + + /* save session key */ + + creds->session.keyvalue.length = 0; + creds->session.keyvalue.data = NULL; + creds->session.keytype = rep->enc_part.key.keytype; + ret = krb5_data_copy (&creds->session.keyvalue, + rep->enc_part.key.keyvalue.data, + rep->enc_part.key.keyvalue.length); + if (ret) { + krb5_clear_error_string(context); + goto out; + } + + /* + * HACK: + * this is really a ugly hack, to support using the Netbios Domain Name + * as realm against windows KDC's, they always return the full realm + * based on the DNS Name. + */ + flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; + flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; + - ret = _krb5_principalname2krb5_principal (context, + /* compare client and save */ + ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.cname, rep->kdc_rep.crealm); if (ret) goto out; - /* compare client */ - - if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0){ - tmp = krb5_principal_compare (context, tmp_principal, creds->client); - if (!tmp) { + /* check client referral and save principal */ + /* anonymous here ? */ + if((flags & EXTRACT_TICKET_ALLOW_CNAME_MISMATCH) == 0) { + ret = check_client_referral(context, rep, + creds->client, + tmp_principal, + &creds->session); + if (ret) { krb5_free_principal (context, tmp_principal); - krb5_clear_error_string (context); - ret = KRB5KRB_AP_ERR_MODIFIED; goto out; } } - krb5_free_principal (context, creds->client); creds->client = tmp_principal; - /* extract ticket */ - ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, - &rep->kdc_rep.ticket, &len, ret); - if(ret) - goto out; - if (creds->ticket.length != len) - krb5_abortx(context, "internal error in ASN.1 encoder"); - creds->second_ticket.length = 0; - creds->second_ticket.data = NULL; - - /* compare server */ - + /* check server referral and save principal */ ret = _krb5_principalname2krb5_principal (context, &tmp_principal, rep->kdc_rep.ticket.sname, rep->kdc_rep.ticket.realm); if (ret) goto out; - if(flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH){ - krb5_free_principal(context, creds->server); - creds->server = tmp_principal; - tmp_principal = NULL; - } else { - tmp = krb5_principal_compare (context, tmp_principal, - creds->server); - krb5_free_principal (context, tmp_principal); - if (!tmp) { - ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_clear_error_string (context); + if((flags & EXTRACT_TICKET_ALLOW_SERVER_MISMATCH) == 0){ + ret = check_server_referral(context, + rep, + flags, + creds->server, + tmp_principal, + &creds->session); + if (ret) { + krb5_free_principal (context, tmp_principal); goto out; } } - - /* decrypt */ - - if (decrypt_proc == NULL) - decrypt_proc = decrypt_tkt; - - ret = (*decrypt_proc)(context, key, key_usage, decryptarg, rep); - if (ret) - goto out; + krb5_free_principal(context, creds->server); + creds->server = tmp_principal; /* verify names */ if(flags & EXTRACT_TICKET_MATCH_REALM){ @@ -227,7 +449,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; if (nonce != rep->enc_part.nonce) { ret = KRB5KRB_AP_ERR_MODIFIED; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -254,7 +476,7 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; if (creds->times.starttime == 0 && abs(tmp_time - sec_now) > context->max_skew) { ret = KRB5KRB_AP_ERR_SKEW; - krb5_set_error_string (context, + krb5_set_error_message (context, ret, "time skew (%d) larger than max (%d)", abs(tmp_time - sec_now), (int)context->max_skew); @@ -307,12 +529,17 @@ flags |=EXTRACT_TICKET_ALLOW_CNAME_MISMATCH ; creds->authdata.len = 0; creds->authdata.val = NULL; - creds->session.keyvalue.length = 0; - creds->session.keyvalue.data = NULL; - creds->session.keytype = rep->enc_part.key.keytype; - ret = krb5_data_copy (&creds->session.keyvalue, - rep->enc_part.key.keyvalue.data, - rep->enc_part.key.keyvalue.length); + + /* extract ticket */ + ASN1_MALLOC_ENCODE(Ticket, creds->ticket.data, creds->ticket.length, + &rep->kdc_rep.ticket, &len, ret); + if(ret) + goto out; + if (creds->ticket.length != len) + krb5_abortx(context, "internal error in ASN.1 encoder"); + creds->second_ticket.length = 0; + creds->second_ticket.data = NULL; + out: memset (rep->enc_part.key.keyvalue.data, 0, @@ -402,7 +629,7 @@ add_padata(krb5_context context, } pa2 = realloc (md->val, (md->len + netypes) * sizeof(*md->val)); if (pa2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } md->val = pa2; @@ -449,13 +676,13 @@ init_as_req (krb5_context context, a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->req_body.sname = malloc(sizeof(*a->req_body.sname)); if (a->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } ret = _krb5_principal2principalname (a->req_body.cname, creds->client); @@ -472,7 +699,7 @@ init_as_req (krb5_context context, a->req_body.from = malloc(sizeof(*a->req_body.from)); if (a->req_body.from == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.from = creds->times.starttime; @@ -485,7 +712,7 @@ init_as_req (krb5_context context, a->req_body.rtime = malloc(sizeof(*a->req_body.rtime)); if (a->req_body.rtime == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.rtime = creds->times.renew_till; @@ -508,7 +735,7 @@ init_as_req (krb5_context context, a->req_body.addresses = malloc(sizeof(*a->req_body.addresses)); if (a->req_body.addresses == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -533,7 +760,7 @@ init_as_req (krb5_context context, ALLOC(a->padata, 1); if(a->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->padata->val = NULL; @@ -572,7 +799,7 @@ init_as_req (krb5_context context, ALLOC(a->padata, 1); if (a->padata == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->padata->len = 0; @@ -590,9 +817,9 @@ init_as_req (krb5_context context, key_proc, keyseed, a->req_body.etype.val, a->req_body.etype.len, &salt); } else { - krb5_set_error_string (context, "pre-auth type %d not supported", - *ptypes); ret = KRB5_PREAUTH_BAD_TYPE; + krb5_set_error_message (context, ret, "pre-auth type %d not supported", + *ptypes); goto fail; } return 0; diff --git a/source4/heimdal/lib/krb5/init_creds.c b/source4/heimdal/lib/krb5/init_creds.c index a59c903bd9..74c9ff78e5 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 21711 2007-07-27 14:22:02Z lha $"); +RCSID("$Id: init_creds.c 23316 2008-06-23 04:32:32Z lha $"); void KRB5_LIB_FUNCTION krb5_get_init_creds_opt_init(krb5_get_init_creds_opt *opt) @@ -52,13 +52,13 @@ krb5_get_init_creds_opt_alloc(krb5_context context, *opt = NULL; o = calloc(1, sizeof(*o)); if (o == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_get_init_creds_opt_init(o); o->opt_private = calloc(1, sizeof(*o->opt_private)); if (o->opt_private == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(o); return ENOMEM; } @@ -77,7 +77,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context, *out = NULL; opt = calloc(1, sizeof(*opt)); if (opt == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (in) @@ -85,7 +85,7 @@ _krb5_get_init_creds_opt_copy(krb5_context context, if(opt->opt_private == NULL) { opt->opt_private = calloc(1, sizeof(*opt->opt_private)); if (opt->opt_private == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(opt); return ENOMEM; } @@ -327,7 +327,7 @@ require_ext_opt(krb5_context context, const char *type) { if (opt->opt_private == NULL) { - krb5_set_error_string(context, "%s on non extendable opt", type); + krb5_set_error_message(context, EINVAL, "%s on non extendable opt", type); return EINVAL; } return 0; @@ -381,7 +381,7 @@ krb5_get_init_creds_opt_get_error(krb5_context context, *error = malloc(sizeof(**error)); if (*error == NULL) { - krb5_set_error_string(context, "malloc - out memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 441adff8fd..e3098b0a92 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 21931 2007-08-27 14:11:55Z lha $"); +RCSID("$Id: init_creds_pw.c 23316 2008-06-23 04:32:32Z lha $"); typedef struct krb5_get_init_creds_ctx { KDCOptions flags; @@ -165,14 +165,10 @@ init_cred (krb5_context context, } if (in_tkt_service) { - krb5_realm server_realm; - ret = krb5_parse_name (context, in_tkt_service, &cred->server); if (ret) goto out; - server_realm = strdup (client_realm); - free (*krb5_princ_realm(context, cred->server)); - krb5_princ_set_realm (context, cred->server, &server_realm); + krb5_principal_set_realm (context, cred->server, client_realm); } else { ret = krb5_make_principal(context, &cred->server, client_realm, KRB5_TGS_NAME, client_realm, @@ -340,7 +336,7 @@ get_init_creds_common(krb5_context context, etypes = malloc((options->etype_list_length + 1) * sizeof(krb5_enctype)); if (etypes == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (etypes, options->etype_list, @@ -352,7 +348,7 @@ get_init_creds_common(krb5_context context, pre_auth_types = malloc((options->preauth_list_length + 1) * sizeof(krb5_preauthtype)); if (pre_auth_types == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (pre_auth_types, options->preauth_list, @@ -445,12 +441,13 @@ change_password (krb5_context context, memset (buf2, 0, sizeof(buf2)); } - ret = krb5_change_password (context, - &cpw_cred, - buf1, - &result_code, - &result_code_string, - &result_string); + ret = krb5_set_password (context, + &cpw_cred, + buf1, + client, + &result_code, + &result_code_string, + &result_string); if (ret) goto out; asprintf (&p, "%s: %.*s\n", @@ -464,8 +461,8 @@ change_password (krb5_context context, strlcpy (newpw, buf1, newpw_sz); ret = 0; } else { - krb5_set_error_string (context, "failed changing password"); ret = ENOTTY; + krb5_set_error_message(context, ret, "failed changing password"); } out: @@ -507,8 +504,8 @@ krb5_get_init_creds_keytab(krb5_context context, a = malloc (sizeof(*a)); if (a == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } a->principal = ctx.cred.client; @@ -560,13 +557,13 @@ init_creds_init_as_req (krb5_context context, a->req_body.cname = malloc(sizeof(*a->req_body.cname)); if (a->req_body.cname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } a->req_body.sname = malloc(sizeof(*a->req_body.sname)); if (a->req_body.sname == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -585,7 +582,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.from = malloc(sizeof(*a->req_body.from)); if (a->req_body.from == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.from = creds->times.starttime; @@ -598,7 +595,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.rtime = malloc(sizeof(*a->req_body.rtime)); if (a->req_body.rtime == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } *a->req_body.rtime = creds->times.renew_till; @@ -621,7 +618,7 @@ init_creds_init_as_req (krb5_context context, a->req_body.addresses = malloc(sizeof(*a->req_body.addresses)); if (a->req_body.addresses == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } @@ -1036,7 +1033,7 @@ pa_data_to_md_pkinit(krb5_context context, ctx->pk_nonce, md); #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); + krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in"); return EINVAL; #endif } @@ -1093,7 +1090,7 @@ process_pa_data_to_md(krb5_context context, ALLOC(*out_md, 1); if (*out_md == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*out_md)->len = 0; @@ -1191,15 +1188,15 @@ process_pa_data_to_key(krb5_context context, pa, key); #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); ret = EINVAL; + krb5_set_error_message(context, ret, "no support for PKINIT compiled in"); #endif } else if (ctx->password) ret = pa_data_to_key_plain(context, creds->client, ctx, paid.salt, paid.s2kparams, etype, key); else { - krb5_set_error_string(context, "No usable pa data type"); ret = EINVAL; + krb5_set_error_message(context, ret, "No usable pa data type"); } free_paid(context, &paid); @@ -1325,8 +1322,8 @@ init_cred_loop(krb5_context context, &md, NULL); if (ret) - krb5_set_error_string(context, - "failed to decode METHOD DATA"); + krb5_set_error_message(context, ret, + "failed to decode METHOD DATA"); } else { /* XXX guess what the server want here add add md */ } @@ -1348,15 +1345,16 @@ init_cred_loop(krb5_context context, { krb5_keyblock *key = NULL; - unsigned flags = 0; + unsigned flags = EXTRACT_TICKET_AS_REQ; if (ctx->flags.request_anonymous) flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; if (ctx->flags.canonicalize) { - flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; flags |= EXTRACT_TICKET_ALLOW_SERVER_MISMATCH; flags |= EXTRACT_TICKET_MATCH_REALM; } + if (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) + flags |= EXTRACT_TICKET_ALLOW_CNAME_MISMATCH; ret = process_pa_data_to_key(context, ctx, creds, &ctx->as_req, &rep, hi, &key); @@ -1376,60 +1374,6 @@ init_cred_loop(krb5_context context, NULL); krb5_free_keyblock(context, key); } - /* - * Verify referral data - */ - if ((ctx->ic_flags & KRB5_INIT_CREDS_CANONICALIZE) && - (ctx->ic_flags & KRB5_INIT_CREDS_NO_C_CANON_CHECK) == 0) - { - PA_ClientCanonicalized canon; - krb5_crypto crypto; - krb5_data data; - PA_DATA *pa; - size_t len; - - pa = find_pa_data(rep.kdc_rep.padata, KRB5_PADATA_CLIENT_CANONICALIZED); - if (pa == NULL) { - ret = EINVAL; - krb5_set_error_string(context, "Client canonicalizion not signed"); - goto out; - } - - ret = decode_PA_ClientCanonicalized(pa->padata_value.data, - pa->padata_value.length, - &canon, &len); - if (ret) { - krb5_set_error_string(context, "Failed to decode " - "PA_ClientCanonicalized"); - goto out; - } - - ASN1_MALLOC_ENCODE(PA_ClientCanonicalizedNames, data.data, data.length, - &canon.names, &len, ret); - if (ret) - goto out; - if (data.length != len) - krb5_abortx(context, "internal asn.1 error"); - - ret = krb5_crypto_init(context, &creds->session, 0, &crypto); - if (ret) { - free(data.data); - free_PA_ClientCanonicalized(&canon); - goto out; - } - - ret = krb5_verify_checksum(context, crypto, KRB5_KU_CANONICALIZED_NAMES, - data.data, data.length, - &canon.canon_checksum); - krb5_crypto_destroy(context, crypto); - free(data.data); - free_PA_ClientCanonicalized(&canon); - if (ret) { - krb5_set_error_string(context, "Failed to verify " - "client canonicalized data"); - goto out; - } - } out: if (stctx) krb5_sendto_ctx_free(context, stctx); diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index 8afaa6ea80..0c91fbb3a0 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 22108 2007-12-03 17:23:53Z lha $"); +RCSID("$Id: kcm.c 23446 2008-07-27 12:08:37Z lha $"); typedef struct krb5_kcmcache { char *name; @@ -56,7 +56,8 @@ typedef struct krb5_kcmcache { #define KCMCURSOR(C) (*(uint32_t *)(C)) static krb5_error_code -try_door(krb5_context context, const krb5_kcmcache *k, +try_door(krb5_context context, + krb5_kcmcache *k, krb5_data *request_data, krb5_data *response_data) { @@ -70,6 +71,7 @@ try_door(krb5_context context, const krb5_kcmcache *k, fd = open(k->door_path, O_RDWR); if (fd < 0) return KRB5_CC_IO; + rk_cloexec(fd); arg.data_ptr = request_data->data; arg.data_size = request_data->length; @@ -95,7 +97,8 @@ try_door(krb5_context context, const krb5_kcmcache *k, } static krb5_error_code -try_unix_socket(krb5_context context, const krb5_kcmcache *k, +try_unix_socket(krb5_context context, + krb5_kcmcache *k, krb5_data *request_data, krb5_data *response_data) { @@ -105,7 +108,8 @@ try_unix_socket(krb5_context context, const krb5_kcmcache *k, fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd < 0) return KRB5_CC_IO; - + rk_cloexec(fd); + if (connect(fd, rk_UNCONST(&k->path), sizeof(k->path)) != 0) { close(fd); return KRB5_CC_IO; @@ -136,7 +140,7 @@ kcm_send_request(krb5_context context, return KRB5_CC_NOMEM; } - ret = KRB5_CC_IO; + ret = KRB5_CC_NOSUPP; for (i = 0; i < context->max_retries; i++) { ret = try_door(context, k, &request_data, response_data); @@ -151,7 +155,7 @@ kcm_send_request(krb5_context context, if (ret) { krb5_clear_error_string(context); - ret = KRB5_CC_IO; + ret = KRB5_CC_NOSUPP; } return ret; @@ -169,7 +173,7 @@ kcm_storage_request(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -187,7 +191,7 @@ kcm_storage_request(krb5_context context, *storage_p = sp; fail: if (ret) { - krb5_set_error_string(context, "Failed to encode request"); + krb5_set_error_message(context, ret, "Failed to encode request"); krb5_storage_free(sp); } @@ -202,7 +206,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id) k = malloc(sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -210,7 +214,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id) k->name = strdup(name); if (k->name == NULL) { free(k); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } } else @@ -822,7 +826,7 @@ kcm_set_flags(krb5_context context, return ret; } -static krb5_error_code +static int kcm_get_version(krb5_context context, krb5_ccache id) { @@ -832,8 +836,30 @@ kcm_get_version(krb5_context context, 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; + krb5_error_code ret; + krb5_kcmcache *oldk = KCMCACHE(from); + krb5_kcmcache *newk = KCMCACHE(to); + krb5_storage *request; + + ret = kcm_storage_request(context, KCM_OP_MOVE_CACHE, &request); + if (ret) + return ret; + + ret = krb5_store_stringz(request, oldk->name); + if (ret) { + krb5_storage_free(request); + return ret; + } + + ret = krb5_store_stringz(request, newk->name); + if (ret) { + krb5_storage_free(request); + return ret; + } + ret = kcm_call(context, oldk, request, NULL, NULL); + + krb5_storage_free(request); + return ret; } static krb5_error_code @@ -850,7 +876,8 @@ kcm_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_kcm_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops = { + KRB5_CC_OPS_VERSION, "KCM", kcm_get_name, kcm_resolve, @@ -1118,5 +1145,4 @@ _krb5_kcm_get_ticket(krb5_context context, return ret; } - #endif /* HAVE_KCM */ diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index ff4f972e57..fa19e1e726 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keyblock.c 15167 2005-05-18 04:21:57Z lha $"); +RCSID("$Id: keyblock.c 23316 2008-06-23 04:32:32Z lha $"); void KRB5_LIB_FUNCTION krb5_keyblock_zero(krb5_keyblock *keyblock) @@ -81,7 +81,7 @@ krb5_copy_keyblock (krb5_context context, k = malloc (sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *to = k; @@ -116,15 +116,16 @@ krb5_keyblock_init(krb5_context context, return ret; if (len != size) { - krb5_set_error_string(context, "Encryption key %d is %lu bytes " - "long, %lu was passed in", - type, (unsigned long)len, (unsigned long)size); + krb5_set_error_message(context, KRB5_PROG_ETYPE_NOSUPP, + "Encryption key %d is %lu bytes " + "long, %lu was passed in", + type, (unsigned long)len, (unsigned long)size); return KRB5_PROG_ETYPE_NOSUPP; } ret = krb5_data_copy(&key->keyvalue, data, len); if(ret) { - krb5_set_error_string(context, "malloc failed: %lu", - (unsigned long)len); + krb5_set_error_message(context, ret, "malloc failed: %lu", + (unsigned long)len); return ret; } key->keytype = type; diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index 79a3f20e79..09e130d850 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 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab.c 23316 2008-06-23 04:32:32Z lha $"); /* * Register a new keytab in `ops' @@ -47,14 +47,15 @@ krb5_kt_register(krb5_context context, struct krb5_keytab_data *tmp; if (strlen(ops->prefix) > KRB5_KT_PREFIX_MAX_LEN - 1) { - krb5_set_error_string(context, "krb5_kt_register; prefix too long"); + krb5_set_error_message(context, KRB5_KT_BADNAME, + "krb5_kt_register; prefix too long"); return KRB5_KT_BADNAME; } tmp = realloc(context->kt_types, (context->num_kt_types + 1) * sizeof(*context->kt_types)); if(tmp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(&tmp[context->num_kt_types], ops, @@ -97,14 +98,15 @@ krb5_kt_resolve(krb5_context context, break; } if(i == context->num_kt_types) { - krb5_set_error_string(context, "unknown keytab type %.*s", - (int)type_len, type); + krb5_set_error_message(context, KRB5_KT_UNKNOWN_TYPE, + "unknown keytab type %.*s", + (int)type_len, type); return KRB5_KT_UNKNOWN_TYPE; } k = malloc (sizeof(*k)); if (k == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(k, &context->kt_types[i], sizeof(*k)); @@ -265,7 +267,7 @@ krb5_kt_get_full_name(krb5_context context, return ret; if (asprintf(str, "%s:%s", type, name) == -1) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); *str = NULL; return ENOMEM; } @@ -377,12 +379,12 @@ krb5_kt_get_entry(krb5_context context, else kvno_str[0] = '\0'; - krb5_set_error_string (context, - "Failed to find %s%s in keytab %s (%s)", - princ, - kvno_str, - kt_name ? kt_name : "unknown keytab", - enctype_str ? enctype_str : "unknown enctype"); + krb5_set_error_message (context, KRB5_KT_NOTFOUND, + "Failed to find %s%s in keytab %s (%s)", + princ, + kvno_str, + kt_name ? kt_name : "unknown keytab", + enctype_str ? enctype_str : "unknown enctype"); free(kt_name); free(enctype_str); return KRB5_KT_NOTFOUND; @@ -443,9 +445,9 @@ krb5_kt_start_seq_get(krb5_context context, krb5_kt_cursor *cursor) { if(id->start_seq_get == NULL) { - krb5_set_error_string(context, - "start_seq_get is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "start_seq_get is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->start_seq_get)(context, id, cursor); @@ -464,9 +466,9 @@ krb5_kt_next_entry(krb5_context context, krb5_kt_cursor *cursor) { if(id->next_entry == NULL) { - krb5_set_error_string(context, - "next_entry is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "next_entry is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->next_entry)(context, id, entry, cursor); @@ -482,9 +484,9 @@ krb5_kt_end_seq_get(krb5_context context, krb5_kt_cursor *cursor) { if(id->end_seq_get == NULL) { - krb5_set_error_string(context, - "end_seq_get is not supported in the %s " - " keytab", id->prefix); + krb5_set_error_message(context, HEIM_ERR_OPNOTSUPP, + "end_seq_get is not supported in the %s " + " keytab", id->prefix); return HEIM_ERR_OPNOTSUPP; } return (*id->end_seq_get)(context, id, cursor); @@ -501,8 +503,9 @@ krb5_kt_add_entry(krb5_context context, krb5_keytab_entry *entry) { if(id->add == NULL) { - krb5_set_error_string(context, "Add is not supported in the %s keytab", - id->prefix); + krb5_set_error_message(context, KRB5_KT_NOWRITE, + "Add is not supported in the %s keytab", + id->prefix); return KRB5_KT_NOWRITE; } entry->timestamp = time(NULL); @@ -520,9 +523,9 @@ krb5_kt_remove_entry(krb5_context context, krb5_keytab_entry *entry) { if(id->remove == NULL) { - krb5_set_error_string(context, - "Remove is not supported in the %s keytab", - id->prefix); + krb5_set_error_message(context, KRB5_KT_NOWRITE, + "Remove is not supported in the %s keytab", + id->prefix); return KRB5_KT_NOWRITE; } return (*id->remove)(context, id, entry); diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c index 54272d4845..9e93191045 100644 --- a/source4/heimdal/lib/krb5/keytab_any.c +++ b/source4/heimdal/lib/krb5/keytab_any.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_any.c 17035 2006-04-10 09:20:13Z lha $"); +RCSID("$Id: keytab_any.c 23316 2008-06-23 04:32:32Z lha $"); struct any_data { krb5_keytab kt; @@ -72,8 +72,8 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id) a0 = a; a->name = strdup(buf); if (a->name == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto fail; } } else @@ -87,7 +87,7 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id) prev = a; } if (a0 == NULL) { - krb5_set_error_string(context, "empty ANY: keytab"); + krb5_set_error_message(context, ENOENT, "empty ANY: keytab"); return ENOENT; } id->data = a0; @@ -134,7 +134,7 @@ any_start_seq_get(krb5_context context, c->data = malloc (sizeof(struct any_cursor_extra_data)); if(c->data == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ed = (struct any_cursor_extra_data *)c->data; @@ -206,8 +206,8 @@ any_add_entry(krb5_context context, while(a != NULL) { ret = krb5_kt_add_entry(context, a->kt, entry); if(ret != 0 && ret != KRB5_KT_NOWRITE) { - krb5_set_error_string(context, "failed to add entry to %s", - a->name); + krb5_set_error_message(context, ret, "failed to add entry to %s", + a->name); return ret; } a = a->next; @@ -229,8 +229,9 @@ any_remove_entry(krb5_context context, found++; else { if(ret != KRB5_KT_NOWRITE && ret != KRB5_KT_NOTFOUND) { - krb5_set_error_string(context, "failed to remove entry from %s", - a->name); + krb5_set_error_message(context, ret, + "Failed to remove keytab entry from %s", + a->name); return ret; } } diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index be195d96c2..e830ab3412 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 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: keytab_file.c 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab_file.c 23469 2008-07-27 12:17:12Z lha $"); #define KRB5_KT_VNO_1 1 #define KRB5_KT_VNO_2 2 @@ -62,7 +62,7 @@ krb5_kt_ret_data(krb5_context context, data->length = size; data->data = malloc(size); if (data->data == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_read(sp, data->data, size); @@ -83,7 +83,7 @@ krb5_kt_ret_string(krb5_context context, return ret; *data = malloc(size + 1); if (*data == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_storage_read(sp, *data, size); @@ -168,22 +168,22 @@ krb5_kt_ret_principal(krb5_context context, ALLOC(p, 1); if(p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = krb5_ret_int16(sp, &len); if(ret) { - krb5_set_error_string(context, - "Failed decoding length of keytab principal"); + krb5_set_error_message(context, ret, + "Failed decoding length of keytab principal"); goto out; } if(krb5_storage_is_flags(sp, KRB5_STORAGE_PRINCIPAL_WRONG_NUM_COMPONENTS)) len--; if (len < 0) { - krb5_set_error_string(context, - "Keytab principal contains invalid length"); ret = KRB5_KT_END; + krb5_set_error_message(context, ret, + "Keytab principal contains invalid length"); goto out; } ret = krb5_kt_ret_string(context, sp, &p->realm); @@ -191,8 +191,8 @@ krb5_kt_ret_principal(krb5_context context, goto out; p->name.name_string.val = calloc(len, sizeof(*p->name.name_string.val)); if(p->name.name_string.val == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } p->name.name_string.len = len; @@ -253,13 +253,13 @@ fkt_resolve(krb5_context context, const char *name, krb5_keytab id) d = malloc(sizeof(*d)); if(d == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->filename = strdup(name); if(d->filename == NULL) { free(d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->flags = 0; @@ -334,10 +334,11 @@ 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, "keytab %s open failed: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "keytab %s open failed: %s", + d->filename, strerror(ret)); return ret; } + rk_cloexec(c->fd); ret = _krb5_xlock(context, c->fd, exclusive, d->filename); if (ret) { close(c->fd); @@ -347,7 +348,7 @@ fkt_start_seq_get_int(krb5_context context, if (c->sp == NULL) { _krb5_xunlock(context, c->fd); close(c->fd); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_eof_code(c->sp, KRB5_KT_END); @@ -492,10 +493,12 @@ fkt_add_entry(krb5_context context, fd = open (d->filename, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", d->filename, + strerror(ret)); return ret; } + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); @@ -510,6 +513,9 @@ fkt_add_entry(krb5_context context, storage_set_flags(context, sp, id->version); } else { int8_t pvno, tag; + + rk_cloexec(fd); + ret = _krb5_xlock(context, fd, 1, d->filename); if (ret) { close(fd); @@ -523,22 +529,22 @@ fkt_add_entry(krb5_context context, properly */ ret = fkt_setup_keytab(context, id, sp); if(ret) { - krb5_set_error_string(context, "%s: keytab is corrupted: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: keytab is corrupted: %s", + d->filename, strerror(ret)); goto out; } storage_set_flags(context, sp, id->version); } else { if(pvno != 5) { ret = KRB5_KEYTAB_BADVNO; - krb5_set_error_string(context, "%s: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: %s", + d->filename, strerror(ret)); goto out; } ret = krb5_ret_int8 (sp, &tag); if (ret) { - krb5_set_error_string(context, "%s: reading tag: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "%s: reading tag: %s", + d->filename, strerror(ret)); goto out; } id->version = tag; @@ -551,7 +557,7 @@ fkt_add_entry(krb5_context context, emem = krb5_storage_emem(); if(emem == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_kt_store_principal(context, emem, entry->principal); diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c index aa612add09..7e14cbd329 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 22532 2008-01-27 11:59:18Z lha $"); +RCSID("$Id: keytab_keyfile.c 23316 2008-06-23 04:32:32Z lha $"); /* afs keyfile operations --------------------------------------- */ @@ -52,7 +52,7 @@ RCSID("$Id: keytab_keyfile.c 22532 2008-01-27 11:59:18Z lha $"); #define AFS_SERVERMAGICKRBCONF "/usr/afs/etc/krb.conf" struct akf_data { - int num_entries; + uint32_t num_entries; char *filename; char *cell; char *realm; @@ -72,13 +72,13 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) f = fopen (AFS_SERVERTHISCELL, "r"); if (f == NULL) { ret = errno; - krb5_set_error_string (context, "open %s: %s", AFS_SERVERTHISCELL, - strerror(ret)); + krb5_set_error_message (context, ret, "open %s: %s", AFS_SERVERTHISCELL, + strerror(ret)); return ret; } if (fgets (buf, sizeof(buf), f) == NULL) { fclose (f); - krb5_set_error_string (context, "no cell in %s", AFS_SERVERTHISCELL); + krb5_set_error_message (context, EINVAL, "no cell in %s", AFS_SERVERTHISCELL); return EINVAL; } buf[strcspn(buf, "\n")] = '\0'; @@ -86,7 +86,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) d->cell = strdup (buf); if (d->cell == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -96,8 +96,8 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) free (d->cell); d->cell = NULL; fclose (f); - krb5_set_error_string (context, "no realm in %s", - AFS_SERVERMAGICKRBCONF); + krb5_set_error_message (context, EINVAL, "no realm in %s", + AFS_SERVERMAGICKRBCONF); return EINVAL; } buf[strcspn(buf, "\n")] = '\0'; @@ -111,7 +111,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) if (d->realm == NULL) { free (d->cell); d->cell = NULL; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -128,7 +128,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id) struct akf_data *d = malloc(sizeof (struct akf_data)); if (d == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -143,7 +143,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id) free (d->cell); free (d->realm); free (d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } id->data = d; @@ -197,13 +197,13 @@ 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, "keytab afs keyfil open %s failed: %s", - d->filename, strerror(ret)); + krb5_set_error_message(context, ret, "keytab afs keyfil open %s failed: %s", + d->filename, strerror(ret)); return ret; } c->sp = krb5_storage_from_fd(c->fd); - ret = krb5_ret_int32(c->sp, &d->num_entries); + ret = krb5_ret_uint32(c->sp, &d->num_entries); if(ret) { krb5_storage_free(c->sp); close(c->fd); @@ -250,7 +250,7 @@ akf_next_entry(krb5_context context, entry->keyblock.keyvalue.data = malloc (8); if (entry->keyblock.keyvalue.data == NULL) { krb5_free_principal (context, entry->principal); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); ret = ENOMEM; goto out; } @@ -307,8 +307,8 @@ akf_add_entry(krb5_context context, O_RDWR | O_BINARY | O_CREAT | O_EXCL, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, "open(%s): %s", d->filename, - strerror(ret)); + krb5_set_error_message(context, ret, "open(%s): %s", d->filename, + strerror(ret)); return ret; } created = 1; @@ -317,7 +317,7 @@ akf_add_entry(krb5_context context, sp = krb5_storage_from_fd(fd); if(sp == NULL) { close(fd); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if (created) @@ -327,7 +327,7 @@ akf_add_entry(krb5_context context, ret = errno; krb5_storage_free(sp); close(fd); - krb5_set_error_string (context, "seek: %s", strerror(ret)); + krb5_set_error_message(context, ret, "seek: %s", strerror(ret)); return ret; } @@ -350,11 +350,12 @@ akf_add_entry(krb5_context context, for (i = 0; i < len; i++) { ret = krb5_ret_int32(sp, &kvno); if (ret) { - krb5_set_error_string (context, "Failed to get kvno "); + krb5_set_error_message (context, ret, "Failed to get kvno "); goto out; } if(krb5_storage_seek(sp, 8, SEEK_CUR) < 0) { - krb5_set_error_string (context, "seek: %s", strerror(ret)); + ret = errno; + krb5_set_error_message (context, ret, "seek: %s", strerror(ret)); goto out; } if (kvno == entry->vno) { @@ -368,25 +369,26 @@ akf_add_entry(krb5_context context, if(krb5_storage_seek(sp, 0, SEEK_SET) < 0) { ret = errno; - krb5_set_error_string (context, "seek: %s", strerror(ret)); + krb5_set_error_message (context, ret, "seek: %s", strerror(ret)); goto out; } ret = krb5_store_int32(sp, len); if(ret) { - krb5_set_error_string(context, "keytab keyfile failed new length"); + ret = errno; + krb5_set_error_message (context, ret, "keytab keyfile failed new length"); return ret; } if(krb5_storage_seek(sp, (len - 1) * (8 + 4), SEEK_CUR) < 0) { ret = errno; - krb5_set_error_string (context, "seek to end: %s", strerror(ret)); + krb5_set_error_message (context, ret, "seek to end: %s", strerror(ret)); goto out; } ret = krb5_store_int32(sp, entry->vno); if(ret) { - krb5_set_error_string(context, "keytab keyfile failed store kvno"); + krb5_set_error_message(context, ret, "keytab keyfile failed store kvno"); goto out; } ret = krb5_storage_write(sp, entry->keyblock.keyvalue.data, @@ -396,7 +398,7 @@ akf_add_entry(krb5_context context, ret = errno; else ret = ENOTTY; - krb5_set_error_string(context, "keytab keyfile failed to add key"); + krb5_set_error_message(context, ret, "keytab keyfile failed to add key"); goto out; } ret = 0; diff --git a/source4/heimdal/lib/krb5/keytab_memory.c b/source4/heimdal/lib/krb5/keytab_memory.c index 0ad8720c3f..eabee7c693 100644 --- a/source4/heimdal/lib/krb5/keytab_memory.c +++ b/source4/heimdal/lib/krb5/keytab_memory.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: keytab_memory.c 16352 2005-12-05 18:39:46Z lha $"); +RCSID("$Id: keytab_memory.c 23293 2008-06-23 03:28:22Z lha $"); /* memory operations -------------------------------------------- */ @@ -75,14 +75,14 @@ mkt_resolve(krb5_context context, const char *name, krb5_keytab id) d = calloc(1, sizeof(*d)); if(d == NULL) { HEIMDAL_MUTEX_unlock(&mkt_mutex); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->name = strdup(name); if (d->name == NULL) { HEIMDAL_MUTEX_unlock(&mkt_mutex); free(d); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->entries = NULL; @@ -176,7 +176,7 @@ mkt_add_entry(krb5_context context, krb5_keytab_entry *tmp; tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } d->entries = tmp; diff --git a/source4/heimdal/lib/krb5/krb5-private.h b/source4/heimdal/lib/krb5/krb5-private.h index 7e04446fe0..867d08e3e5 100644 --- a/source4/heimdal/lib/krb5/krb5-private.h +++ b/source4/heimdal/lib/krb5/krb5-private.h @@ -38,12 +38,6 @@ _krb5_dh_group_ok ( struct krb5_dh_moduli **/*moduli*/, char **/*name*/); -krb5_error_code KRB5_LIB_FUNCTION -_krb5_enctype_to_oid ( - krb5_context /*context*/, - krb5_enctype /*etype*/, - heim_oid */*oid*/); - krb5_error_code _krb5_expand_default_cc_name ( krb5_context /*context*/, @@ -283,12 +277,6 @@ _krb5_n_fold ( void */*key*/, size_t /*size*/); -krb5_error_code KRB5_LIB_FUNCTION -_krb5_oid_to_enctype ( - krb5_context /*context*/, - const heim_oid */*oid*/, - krb5_enctype */*etype*/); - krb5_error_code _krb5_pac_sign ( krb5_context /*context*/, @@ -321,6 +309,20 @@ _krb5_pk_allow_proxy_certificate ( void KRB5_LIB_FUNCTION _krb5_pk_cert_free (struct krb5_pk_cert */*cert*/); +krb5_error_code +_krb5_pk_kdf ( + krb5_context /*context*/, + const struct AlgorithmIdentifier */*ai*/, + const void */*dhdata*/, + size_t /*dhsize*/, + krb5_const_principal /*client*/, + krb5_const_principal /*server*/, + krb5_enctype /*enctype*/, + const krb5_data */*as_req*/, + const krb5_data */*pk_as_rep*/, + const Ticket */*ticket*/, + krb5_keyblock */*key*/); + krb5_error_code KRB5_LIB_FUNCTION _krb5_pk_load_id ( krb5_context /*context*/, @@ -401,6 +403,12 @@ _krb5_principal2principalname ( PrincipalName */*p*/, const krb5_principal /*from*/); +krb5_boolean KRB5_LIB_FUNCTION +_krb5_principal_compare_PrincipalName ( + krb5_context /*context*/, + krb5_const_principal /*princ1*/, + PrincipalName */*princ2*/); + krb5_error_code KRB5_LIB_FUNCTION _krb5_principalname2krb5_principal ( krb5_context /*context*/, diff --git a/source4/heimdal/lib/krb5/krb5-protos.h b/source4/heimdal/lib/krb5/krb5-protos.h index 647d8886b7..ead66565e7 100644 --- a/source4/heimdal/lib/krb5/krb5-protos.h +++ b/source4/heimdal/lib/krb5/krb5-protos.h @@ -12,11 +12,13 @@ extern "C" { #endif -#ifndef KRB5_LIB_FUNCTION +#ifndef KRB5_LIB #if defined(_WIN32) -#define KRB5_LIB_FUNCTION _stdcall +#define KRB5_LIB_FUNCTION _stdcall __declspec(dllimport) +#define KRB5_LIB_VARIABLE __declspec(dllimport) #else #define KRB5_LIB_FUNCTION +#define KRB5_LIB_VARIABLE #endif #endif @@ -628,6 +630,14 @@ krb5_cc_gen_new ( krb5_ccache */*id*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_get_config ( + krb5_context /*context*/, + krb5_ccache /*id*/, + krb5_const_principal /*principal*/, + const char */*name*/, + krb5_data */*data*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_cc_get_full_name ( krb5_context /*context*/, krb5_ccache /*id*/, @@ -727,6 +737,14 @@ krb5_cc_retrieve_cred ( krb5_creds */*creds*/); krb5_error_code KRB5_LIB_FUNCTION +krb5_cc_set_config ( + krb5_context /*context*/, + krb5_ccache /*id*/, + krb5_const_principal /*principal*/, + const char */*name*/, + krb5_data */*data*/); + +krb5_error_code KRB5_LIB_FUNCTION krb5_cc_set_default_name ( krb5_context /*context*/, const char */*name*/); @@ -749,6 +767,11 @@ krb5_cc_store_cred ( krb5_ccache /*id*/, krb5_creds */*creds*/); +krb5_error_code +krb5_cc_switch ( + krb5_context /*context*/, + krb5_ccache /*id*/); + krb5_error_code KRB5_LIB_FUNCTION krb5_change_password ( krb5_context /*context*/, @@ -756,7 +779,8 @@ krb5_change_password ( const char */*newpw*/, int */*result_code*/, krb5_data */*result_code_string*/, - krb5_data */*result_string*/); + krb5_data */*result_string*/) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited ( @@ -764,14 +788,14 @@ krb5_check_transited ( krb5_const_realm /*client_realm*/, krb5_const_realm /*server_realm*/, krb5_realm */*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, int */*bad_realm*/); krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited_realms ( krb5_context /*context*/, const char *const */*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, int */*bad_realm*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1462,14 +1486,14 @@ krb5_domain_x500_decode ( krb5_context /*context*/, krb5_data /*tr*/, char ***/*realms*/, - int */*num_realms*/, + unsigned int */*num_realms*/, const char */*client_realm*/, const char */*server_realm*/); krb5_error_code KRB5_LIB_FUNCTION krb5_domain_x500_encode ( char **/*realms*/, - int /*num_realms*/, + unsigned int /*num_realms*/, krb5_data */*encoding*/); krb5_error_code KRB5_LIB_FUNCTION @@ -1731,9 +1755,9 @@ krb5_free_error_contents ( krb5_error */*error*/); void KRB5_LIB_FUNCTION -krb5_free_error_string ( +krb5_free_error_message ( krb5_context /*context*/, - char */*str*/); + const char */*msg*/); krb5_error_code KRB5_LIB_FUNCTION krb5_free_host_realm ( @@ -1939,7 +1963,7 @@ krb5_get_err_text ( krb5_context /*context*/, krb5_error_code /*code*/); -char * KRB5_LIB_FUNCTION +const char * KRB5_LIB_FUNCTION krb5_get_error_message ( krb5_context /*context*/, krb5_error_code /*code*/); @@ -2969,6 +2993,12 @@ krb5_principal_match ( krb5_const_principal /*princ*/, krb5_const_principal /*pattern*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_principal_set_realm ( + krb5_context /*context*/, + krb5_principal /*principal*/, + krb5_const_realm /*realm*/); + void KRB5_LIB_FUNCTION krb5_principal_set_type ( krb5_context /*context*/, @@ -3450,12 +3480,20 @@ krb5_set_dns_canonicalize_hostname ( krb5_context /*context*/, krb5_boolean /*flag*/); +void KRB5_LIB_FUNCTION +krb5_set_error_message ( + krb5_context /*context*/, + krb5_error_code /*ret*/, + const char */*fmt*/, + ...) + __attribute__ ((format (printf, 3, 4))); + krb5_error_code KRB5_LIB_FUNCTION krb5_set_error_string ( krb5_context /*context*/, const char */*fmt*/, - ...) - __attribute__((format (printf, 2, 3))); + ...) __attribute__((format (printf, 2, 3))) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_set_extra_addresses ( @@ -3472,6 +3510,12 @@ krb5_set_ignore_addresses ( krb5_context /*context*/, const krb5_addresses */*addresses*/); +krb5_error_code KRB5_LIB_FUNCTION +krb5_set_kdc_sec_offset ( + krb5_context /*context*/, + int32_t /*sec*/, + int32_t /*usec*/); + void KRB5_LIB_FUNCTION krb5_set_max_time_skew ( krb5_context /*context*/, @@ -4047,12 +4091,20 @@ krb5_vlog_msg ( va_list /*ap*/) __attribute__((format (printf, 5, 0))); +void KRB5_LIB_FUNCTION +krb5_vset_error_message ( + krb5_context /*context*/, + krb5_error_code /*ret*/, + const char */*fmt*/, + va_list /*args*/) + __attribute__ ((format (printf, 3, 0))); + krb5_error_code KRB5_LIB_FUNCTION krb5_vset_error_string ( krb5_context /*context*/, const char */*fmt*/, - va_list /*args*/) - __attribute__ ((format (printf, 2, 0))); + va_list args) __attribute__ ((format (printf, 2, 0))) + __attribute__((deprecated)); krb5_error_code KRB5_LIB_FUNCTION krb5_vwarn ( @@ -4107,6 +4159,9 @@ krb5_write_safe_message ( krb5_error_code KRB5_LIB_FUNCTION krb5_xfree (void */*ptr*/); +void KRB5_LIB_FUNCTION + __attribute__((deprecated)) krb5_free_error_string(krb5_context context, char *str); + #ifdef __cplusplus } #endif diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 571eb6192a..b1e2781d52 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -31,7 +31,7 @@ * SUCH DAMAGE. */ -/* $Id: krb5.h 22100 2007-12-03 17:15:00Z lha $ */ +/* $Id: krb5.h 23026 2008-04-17 10:02:03Z lha $ */ #ifndef __KRB5_H__ #define __KRB5_H__ @@ -363,6 +363,7 @@ typedef union { #define KRB5_GC_FORWARDABLE (1U << 4) #define KRB5_GC_NO_TRANSIT_CHECK (1U << 5) #define KRB5_GC_CONSTRAINED_DELEGATION (1U << 6) +#define KRB5_GC_CANONICALIZE (1U << 7) /* constants for compare_creds (and cc_retrieve_cred) */ #define KRB5_TC_DONT_MATCH_REALM (1U << 31) @@ -395,7 +396,10 @@ typedef struct krb5_creds { typedef struct krb5_cc_cache_cursor_data *krb5_cc_cache_cursor; +#define KRB5_CC_OPS_VERSION 1 + typedef struct krb5_cc_ops { + int version; const char *prefix; const char* (*get_name)(krb5_context, krb5_ccache); krb5_error_code (*resolve)(krb5_context, krb5_ccache *, const char *); @@ -419,7 +423,8 @@ typedef struct krb5_cc_ops { 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_error_code (*get_default_name)(krb5_context, char **); + krb5_error_code (*set_default)(krb5_context, krb5_ccache); } krb5_cc_ops; struct krb5_log_facility; @@ -589,11 +594,6 @@ typedef EncAPRepPart krb5_ap_rep_enc_part; #define KRB5_DIGEST_NAME ("digest") -/* variables */ - -extern const char *krb5_config_file; -extern const char *krb5_defkeyname; - typedef enum { KRB5_PROMPT_TYPE_PASSWORD = 0x1, KRB5_PROMPT_TYPE_NEW_PASSWORD = 0x2, @@ -681,20 +681,6 @@ typedef struct krb5_verify_opt { #define KRB5_VERIFY_LREALMS 1 #define KRB5_VERIFY_NO_ADDRESSES 2 -extern const krb5_cc_ops krb5_acc_ops; -extern const krb5_cc_ops krb5_fcc_ops; -extern const krb5_cc_ops krb5_mcc_ops; -extern const krb5_cc_ops krb5_kcm_ops; - -extern const krb5_kt_ops krb5_fkt_ops; -extern const krb5_kt_ops krb5_wrfkt_ops; -extern const krb5_kt_ops krb5_javakt_ops; -extern const krb5_kt_ops krb5_mkt_ops; -extern const krb5_kt_ops krb5_akf_ops; -extern const krb5_kt_ops krb4_fkt_ops; -extern const krb5_kt_ops krb5_srvtab_fkt_ops; -extern const krb5_kt_ops krb5_any_ops; - #define KRB5_KPASSWD_VERS_CHANGEPW 1 #define KRB5_KPASSWD_VERS_SETPW 0xff80 @@ -739,6 +725,7 @@ enum { typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, void *, krb5_krbhst_info *, + time_t timeout, const krb5_data *, krb5_data *); @@ -776,5 +763,26 @@ struct sockaddr; #include <krb5-protos.h> +/* variables */ + +extern KRB5_LIB_VARIABLE const char *krb5_config_file; +extern KRB5_LIB_VARIABLE const char *krb5_defkeyname; + + +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_acc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_fcc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_kcm_ops; +extern KRB5_LIB_VARIABLE const krb5_cc_ops krb5_scc_ops; + +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_wrfkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_javakt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_mkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_akf_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb4_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_srvtab_fkt_ops; +extern KRB5_LIB_VARIABLE const krb5_kt_ops krb5_any_ops; + #endif /* __KRB5_H__ */ diff --git a/source4/heimdal/lib/krb5/krb5_err.et b/source4/heimdal/lib/krb5/krb5_err.et index 6714401e45..8e49ffcc4a 100644 --- a/source4/heimdal/lib/krb5/krb5_err.et +++ b/source4/heimdal/lib/krb5/krb5_err.et @@ -3,7 +3,7 @@ # # This might look like a com_err file, but is not # -id "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $" +id "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $" error_table krb5 @@ -110,7 +110,7 @@ error_code PUBLIC_KEY_ENCRYPTION_NOT_SUPPORTED, "Public key encryption not suppo index 128 prefix -error_code KRB5_ERR_RCSID, "$Id: krb5_err.et 21050 2007-06-12 02:00:40Z lha $" +error_code KRB5_ERR_RCSID, "$Id: krb5_err.et 23354 2008-07-15 11:23:34Z lha $" error_code KRB5_LIBOS_BADLOCKFLAG, "Invalid flag for file lock mode" error_code KRB5_LIBOS_CANTREADPWD, "Cannot read password" @@ -262,5 +262,7 @@ error_code KRB5_ERR_BAD_S2K_PARAMS, "Invalid key generation parameters from KDC" error_code KRB5_ERR_NO_SERVICE, "Service not available" error_code KRB5_CC_NOSUPP, "Credential cache function not supported" error_code KRB5_DELTAT_BADFORMAT, "Invalid format of Kerberos lifetime or clock skew string" +error_code KRB5_PLUGIN_NO_HANDLE, "Supplied data not handled by this plugin" +error_code KRB5_PLUGIN_OP_NOTSUPP, "Plugin does not support the operaton" end diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 8b7c41cc80..aaabd4541b 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 22226 2007-12-08 21:31:53Z lha $ */ +/* $Id: krb5_locl.h 23324 2008-06-26 03:54:45Z lha $ */ #ifndef __KRB5_LOCL_H__ #define __KRB5_LOCL_H__ @@ -131,6 +131,8 @@ struct sockaddr_dl; #include <parse_time.h> #include <base64.h> +#include <wind.h> + #include "crypto-headers.h" @@ -142,6 +144,7 @@ struct send_to_kdc; struct krb5_pk_identity; struct krb5_pk_cert; struct ContentInfo; +struct AlgorithmIdentifier; typedef struct krb5_pk_init_ctx_data *krb5_pk_init_ctx; struct krb5_dh_moduli; @@ -154,7 +157,7 @@ struct _krb5_krb_auth_data; #include <krb5_err.h> #include <asn1_err.h> #ifdef PKINIT -#include <hx509_err.h> +#include <hx509.h> #endif #include <krb5-private.h> @@ -164,7 +167,7 @@ struct _krb5_krb_auth_data; #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) /* should this be public? */ -#define KEYTAB_DEFAULT "ANY:FILE:" SYSCONFDIR "/krb5.keytab,krb4:" SYSCONFDIR "/srvtab" +#define KEYTAB_DEFAULT "FILE:" SYSCONFDIR "/krb5.keytab" #define KEYTAB_DEFAULT_MODIFY "FILE:" SYSCONFDIR "/krb5.keytab" #define MODULI_FILE SYSCONFDIR "/krb5.moduli" @@ -227,7 +230,7 @@ typedef struct krb5_context_data { struct krb5_keytab_data *kt_types; /* registered keytab types */ const char *date_fmt; char *error_string; - char error_buf[256]; + krb5_error_code error_code; krb5_addresses *ignore_addresses; char *default_cc_name; char *default_cc_name_env; @@ -247,6 +250,7 @@ typedef struct krb5_context_data { #define EXTRACT_TICKET_ALLOW_CNAME_MISMATCH 1 #define EXTRACT_TICKET_ALLOW_SERVER_MISMATCH 2 #define EXTRACT_TICKET_MATCH_REALM 4 +#define EXTRACT_TICKET_AS_REQ 8 /* * Configurable options @@ -264,4 +268,22 @@ typedef struct krb5_context_data { #define KRB5_ADDRESSLESS_DEFAULT TRUE #endif +#ifdef PKINIT + +struct krb5_pk_identity { + hx509_context hx509ctx; + hx509_verify_ctx verify_ctx; + hx509_certs certs; + hx509_certs anchors; + hx509_certs certpool; + hx509_revoke_ctx revokectx; +}; + +enum krb5_pk_type { + PKINIT_WIN2K = 1, + PKINIT_27 = 2 +}; + +#endif /* PKINIT */ + #endif /* __KRB5_LOCL_H__ */ diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index 094fd4f9c6..3514a026b7 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -35,7 +35,7 @@ #include <resolve.h> #include "locate_plugin.h" -RCSID("$Id: krbhst.c 21457 2007-07-10 12:53:25Z lha $"); +RCSID("$Id: krbhst.c 23447 2008-07-27 12:09:05Z lha $"); static int string_to_proto(const char *string) @@ -72,7 +72,8 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, proto_num = string_to_proto(proto); if(proto_num < 0) { - krb5_set_error_string(context, "unknown protocol `%s'", proto); + krb5_set_error_message(context, EINVAL, + "unknown protocol `%s'", proto); return EINVAL; } @@ -96,7 +97,7 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count, *res = malloc(num_srv * sizeof(**res)); if(*res == NULL) { dns_free_data(r); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -247,7 +248,7 @@ _krb5_krbhost_info_move(krb5_context context, /* trailing NUL is included in structure */ *to = calloc(1, sizeof(**to) + hostnamelen); if(*to == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -522,7 +523,8 @@ plugin_get_hosts(krb5_context context, struct krb5_plugin *list = NULL, *e; krb5_error_code ret; - ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, "resolve", &list); + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, + KRB5_PLUGIN_LOCATE, &list); if(ret != 0 || list == NULL) return; @@ -539,8 +541,9 @@ plugin_get_hosts(krb5_context context, (*service->init)(context, &ctx); ret = (*service->lookup)(ctx, type, kd->realm, 0, 0, add_locate, kd); (*service->fini)(ctx); - if (ret) { - krb5_set_error_string(context, "Plugin failed to lookup"); + if (ret && ret != KRB5_PLUGIN_NO_HANDLE) { + krb5_set_error_message(context, ret, + "Locate plugin failed to lookup: %d", ret); break; } } @@ -832,7 +835,7 @@ krb5_krbhst_init_flags(krb5_context context, def_port = ntohs(krb5_getportbyname (context, "krb524", "udp", 4444)); break; default: - krb5_set_error_string(context, "unknown krbhst type (%u)", type); + krb5_set_error_message(context, ENOTTY, "unknown krbhst type (%u)", type); return ENOTTY; } if((kd = common_init(context, realm, flags)) == NULL) @@ -920,7 +923,8 @@ gethostlist(krb5_context context, const char *realm, while(krb5_krbhst_next(context, handle, &hostinfo) == 0) nhost++; if(nhost == 0) { - krb5_set_error_string(context, "No KDC found for realm %s", realm); + krb5_set_error_message(context, KRB5_KDC_UNREACH, + "No KDC found for realm %s", realm); return KRB5_KDC_UNREACH; } *hostlist = calloc(nhost + 1, sizeof(**hostlist)); diff --git a/source4/heimdal/lib/krb5/locate_plugin.h b/source4/heimdal/lib/krb5/locate_plugin.h index 251712c894..a342617d38 100644 --- a/source4/heimdal/lib/krb5/locate_plugin.h +++ b/source4/heimdal/lib/krb5/locate_plugin.h @@ -31,13 +31,15 @@ * SUCH DAMAGE. */ -/* $Id: locate_plugin.h 18998 2006-11-12 19:00:03Z lha $ */ +/* $Id: locate_plugin.h 23351 2008-07-15 11:22:39Z lha $ */ #ifndef HEIMDAL_KRB5_LOCATE_PLUGIN_H #define HEIMDAL_KRB5_LOCATE_PLUGIN_H 1 #include <krb5.h> +#define KRB5_PLUGIN_LOCATE "resolve" + enum locate_service_type { locate_service_kdc = 1, locate_service_master_kdc, diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index c04f50fd9a..721e3691ca 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: log.c 19088 2006-11-21 08:08:46Z lha $"); +RCSID("$Id: log.c 23443 2008-07-27 12:07:25Z lha $"); struct facility { int min; @@ -121,13 +121,13 @@ krb5_initlog(krb5_context context, { krb5_log_facility *f = calloc(1, sizeof(*f)); if(f == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } f->program = strdup(program); if(f->program == NULL){ free(f); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *fac = f; @@ -145,7 +145,7 @@ krb5_addlog_func(krb5_context context, { struct facility *fp = log_realloc(fac); if(fp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } fp->min = min; @@ -187,7 +187,7 @@ open_syslog(krb5_context context, int i; if(sd == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } i = find_value(sev, syslogvals); @@ -242,7 +242,7 @@ open_file(krb5_context context, krb5_log_facility *fac, int min, int max, { struct file_data *fd = malloc(sizeof(*fd)); if(fd == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } fd->filename = filename; @@ -277,7 +277,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) if(n){ p = strchr(p, '/'); if(p == NULL) { - krb5_set_error_string (context, "failed to parse \"%s\"", orig); + krb5_set_error_message(context, HEIM_ERR_LOG_PARSE, + "failed to parse \"%s\"", orig); return HEIM_ERR_LOG_PARSE; } p++; @@ -292,7 +293,7 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) int keep_open = 0; fn = strdup(p + 5); if(fn == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(p[4] == '='){ @@ -300,16 +301,17 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) O_TRUNC | O_APPEND, 0666); if(i < 0) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", fn, + krb5_set_error_message(context, ret, "open(%s): %s", fn, strerror(ret)); free(fn); return ret; } + rk_cloexec(i); file = fdopen(i, "a"); if(file == NULL){ ret = errno; close(i); - krb5_set_error_string (context, "fdopen(%s): %s", fn, + krb5_set_error_message(context, ret, "fdopen(%s): %s", fn, strerror(ret)); free(fn); return ret; @@ -333,8 +335,8 @@ krb5_addlog_dest(krb5_context context, krb5_log_facility *f, const char *orig) strlcpy(facility, "AUTH", sizeof(facility)); ret = open_syslog(context, f, min, max, severity, facility); }else{ - krb5_set_error_string (context, "unknown log type: %s", p); ret = HEIM_ERR_LOG_PARSE; /* XXX */ + krb5_set_error_message (context, ret, "unknown log type: %s", p); } return ret; } diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c index 01bcb09d3b..682f9f6abd 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 22107 2007-12-03 17:22:51Z lha $"); +RCSID("$Id: mcache.c 23316 2008-06-23 04:32:32Z lha $"); typedef struct krb5_mcache { char *name; @@ -119,7 +119,7 @@ mcc_resolve(krb5_context context, krb5_ccache *id, const char *res) m = mcc_alloc(res); if (m == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -138,7 +138,7 @@ mcc_gen_new(krb5_context context, krb5_ccache *id) m = mcc_alloc(NULL); if (m == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } @@ -237,7 +237,7 @@ mcc_store_cred(krb5_context context, l = malloc (sizeof(*l)); if (l == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_CC_NOMEM, "malloc: out of memory"); return KRB5_CC_NOMEM; } l->next = m->creds; @@ -348,7 +348,7 @@ mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) iter = calloc(1, sizeof(*iter)); if (iter == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -439,7 +439,7 @@ mcc_default_name(krb5_context context, char **str) { *str = strdup("MEMORY:"); if (*str == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -452,7 +452,8 @@ mcc_default_name(krb5_context context, char **str) * @ingroup krb5_ccache */ -const krb5_cc_ops krb5_mcc_ops = { +KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops = { + KRB5_CC_OPS_VERSION, "MEMORY", mcc_get_name, mcc_resolve, diff --git a/source4/heimdal/lib/krb5/mk_priv.c b/source4/heimdal/lib/krb5/mk_priv.c index 87e429af8c..3b4b6e30b7 100644 --- a/source4/heimdal/lib/krb5/mk_priv.c +++ b/source4/heimdal/lib/krb5/mk_priv.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_priv.c 16680 2006-02-01 12:39:26Z lha $"); +RCSID("$Id: mk_priv.c 23297 2008-06-23 03:28:53Z lha $"); krb5_error_code KRB5_LIB_FUNCTION @@ -138,7 +138,7 @@ krb5_mk_priv(krb5_context context, ret = krb5_data_copy(outbuf, buf + buf_size - len, len); if (ret) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free(buf); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/mk_rep.c b/source4/heimdal/lib/krb5/mk_rep.c index 570a837201..069df42e26 100644 --- a/source4/heimdal/lib/krb5/mk_rep.c +++ b/source4/heimdal/lib/krb5/mk_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: mk_rep.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: mk_rep.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_mk_rep(krb5_context context, @@ -61,18 +61,18 @@ krb5_mk_rep(krb5_context context, auth_context, auth_context->keyblock); if(ret) { - krb5_set_error_string (context, - "krb5_mk_rep: generating subkey"); free_EncAPRepPart(&body); + krb5_set_error_message(context, ret, + "krb5_mk_rep: generating subkey"); return ret; } } ret = krb5_copy_keyblock(context, auth_context->local_subkey, &body.subkey); if (ret) { - krb5_set_error_string (context, - "krb5_copy_keyblock: out of memory"); free_EncAPRepPart(&body); + krb5_set_error_message(context, ENOMEM, + "krb5_copy_keyblock: out of memory"); return ENOMEM; } } else @@ -84,7 +84,7 @@ krb5_mk_rep(krb5_context context, &auth_context->local_seqnumber); ALLOC(body.seq_number, 1); if (body.seq_number == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); free_EncAPRepPart(&body); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/n-fold.c b/source4/heimdal/lib/krb5/n-fold.c index 53528cfd1f..287f8cf64f 100644 --- a/source4/heimdal/lib/krb5/n-fold.c +++ b/source4/heimdal/lib/krb5/n-fold.c @@ -32,7 +32,7 @@ #include "krb5_locl.h" -RCSID("$Id: n-fold.c 22190 2007-12-06 16:24:22Z lha $"); +RCSID("$Id: n-fold.c 22923 2008-04-08 14:51:33Z lha $"); static krb5_error_code rr13(unsigned char *buf, size_t len) diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c index 0b44ca1da3..fbc754efda 100644 --- a/source4/heimdal/lib/krb5/pac.c +++ b/source4/heimdal/lib/krb5/pac.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <wind.h> -RCSID("$Id: pac.c 22562 2008-02-03 17:38:35Z lha $"); +RCSID("$Id: pac.c 23316 2008-06-23 04:32:32Z lha $"); struct PAC_INFO_BUFFER { uint32_t type; @@ -93,14 +93,14 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, p = calloc(1, sizeof(*p)); if (p == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } sp = krb5_storage_from_readonly_mem(ptr, len); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -108,21 +108,21 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, CHECK(ret, krb5_ret_uint32(sp, &tmp), out); CHECK(ret, krb5_ret_uint32(sp, &tmp2), out); if (tmp < 1) { - krb5_set_error_string(context, "PAC have too few buffer"); ret = EINVAL; /* Too few buffers */ + krb5_set_error_message(context, ret, "PAC have too few buffer"); goto out; } if (tmp2 != 0) { - krb5_set_error_string(context, "PAC have wrong version"); ret = EINVAL; /* Wrong version */ + krb5_set_error_message(context, ret, "PAC have wrong version"); goto out; } p->pac = calloc(1, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (tmp - 1))); if (p->pac == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -143,51 +143,52 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, /* consistency checks */ if (p->pac->buffers[i].offset_lo & (PAC_ALIGNMENT - 1)) { - krb5_set_error_string(context, "PAC out of allignment"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC out of allignment"); goto out; } if (p->pac->buffers[i].offset_hi) { - krb5_set_error_string(context, "PAC high offset set"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC high offset set"); goto out; } if (p->pac->buffers[i].offset_lo > len) { - krb5_set_error_string(context, "PAC offset off end"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC offset off end"); goto out; } if (p->pac->buffers[i].offset_lo < header_end) { - krb5_set_error_string(context, "PAC offset inside header: %d %d", - p->pac->buffers[i].offset_lo, header_end); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC offset inside header: %lu %lu", + (unsigned long)p->pac->buffers[i].offset_lo, + (unsigned long)header_end); goto out; } if (p->pac->buffers[i].buffersize > len - p->pac->buffers[i].offset_lo){ - krb5_set_error_string(context, "PAC length off end"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC length off end"); goto out; } /* let save pointer to data we need later */ if (p->pac->buffers[i].type == PAC_SERVER_CHECKSUM) { if (p->server_checksum) { - krb5_set_error_string(context, "PAC have two server checksums"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two server checksums"); goto out; } p->server_checksum = &p->pac->buffers[i]; } else if (p->pac->buffers[i].type == PAC_PRIVSVR_CHECKSUM) { if (p->privsvr_checksum) { - krb5_set_error_string(context, "PAC have two KDC checksums"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two KDC checksums"); goto out; } p->privsvr_checksum = &p->pac->buffers[i]; } else if (p->pac->buffers[i].type == PAC_LOGON_NAME) { if (p->logon_name) { - krb5_set_error_string(context, "PAC have two logon names"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC have two logon names"); goto out; } p->logon_name = &p->pac->buffers[i]; @@ -224,14 +225,14 @@ krb5_pac_init(krb5_context context, krb5_pac *pac) p = calloc(1, sizeof(*p)); if (p == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = calloc(1, sizeof(*p->pac)); if (p->pac == NULL) { free(p); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -239,7 +240,7 @@ krb5_pac_init(krb5_context context, krb5_pac *pac) if (ret) { free (p->pac); free(p); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } @@ -262,7 +263,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * len)); if (ptr == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = ptr; @@ -280,7 +281,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, old_end = p->data.length; len = p->data.length + data->length + PAC_INFO_BUFFER_SIZE; if (len < p->data.length) { - krb5_set_error_string(context, "integer overrun"); + krb5_set_error_message(context, EINVAL, "integer overrun"); return EINVAL; } @@ -289,7 +290,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, ret = krb5_data_realloc(&p->data, len); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } @@ -330,7 +331,7 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, if (type == PAC_PRIVSVR_CHECKSUM || type == PAC_SERVER_CHECKSUM) { ret = krb5_data_alloc(data, 16); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } memset(data->data, 0, data->length); @@ -346,13 +347,13 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, ret = krb5_data_copy(data, (unsigned char *)p->data.data + offset, len); if (ret) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; } return 0; } - krb5_set_error_string(context, "No PAC buffer of type %lu was found", - (unsigned long)type); + krb5_set_error_message(context, ENOENT, "No PAC buffer of type %lu was found", + (unsigned long)type); return ENOENT; } @@ -371,7 +372,7 @@ krb5_pac_get_types(krb5_context context, *types = calloc(p->pac->numbuffers, sizeof(*types)); if (*types == NULL) { *len = 0; - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } for (i = 0; i < p->pac->numbuffers; i++) @@ -415,7 +416,7 @@ verify_checksum(krb5_context context, sp = krb5_storage_from_mem((char *)data->data + sig->offset_lo, sig->buffersize); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -426,21 +427,21 @@ verify_checksum(krb5_context context, sig->buffersize - krb5_storage_seek(sp, 0, SEEK_CUR); cksum.checksum.data = malloc(cksum.checksum.length); if (cksum.checksum.data == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length); if (ret != cksum.checksum.length) { - krb5_set_error_string(context, "PAC checksum missing checksum"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC checksum missing checksum"); goto out; } if (!krb5_checksum_is_keyed(context, cksum.cksumtype)) { - krb5_set_error_string (context, "Checksum type %d not keyed", - cksum.cksumtype); ret = EINVAL; + krb5_set_error_message(context, ret, "Checksum type %d not keyed", + cksum.cksumtype); goto out; } @@ -487,7 +488,7 @@ create_checksum(krb5_context context, return ret; if (cksum.checksum.length != siglen) { - krb5_set_error_string(context, "pac checksum wrong length"); + krb5_set_error_message(context, EINVAL, "pac checksum wrong length"); free_Checksum(&cksum); return EINVAL; } @@ -530,7 +531,7 @@ verify_logonname(krb5_context context, sp = krb5_storage_from_readonly_mem((const char *)data->data + logon_name->offset_lo, logon_name->buffersize); if (sp == NULL) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -545,27 +546,27 @@ verify_logonname(krb5_context context, t2 = ((uint64_t)time2 << 32) | time1; if (t1 != t2) { krb5_storage_free(sp); - krb5_set_error_string(context, "PAC timestamp mismatch"); + krb5_set_error_message(context, EINVAL, "PAC timestamp mismatch"); return EINVAL; } } CHECK(ret, krb5_ret_uint16(sp, &len), out); if (len == 0) { krb5_storage_free(sp); - krb5_set_error_string(context, "PAC logon name length missing"); + krb5_set_error_message(context, EINVAL, "PAC logon name length missing"); return EINVAL; } s = malloc(len); if (s == NULL) { krb5_storage_free(sp); - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } 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_message(context, EINVAL, "Failed to read PAC logon name"); return EINVAL; } krb5_storage_free(sp); @@ -577,33 +578,33 @@ verify_logonname(krb5_context context, ucs2 = malloc(sizeof(ucs2[0]) * ucs2len); if (ucs2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len); free(s); if (ret) { free(ucs2); - krb5_set_error_string(context, "Failed to convert string to UCS-2"); + krb5_set_error_message(context, ret, "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"); + krb5_set_error_message(context, ret, "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"); + krb5_set_error_message(context, ENOMEM, "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"); + krb5_set_error_message(context, ret, "Failed to convert to UTF-8"); return ret; } } @@ -613,8 +614,8 @@ verify_logonname(krb5_context context, return ret; if (krb5_principal_compare_any_realm(context, principal, p2) != TRUE) { - krb5_set_error_string(context, "PAC logon name mismatch"); ret = EINVAL; + krb5_set_error_message(context, ret, "PAC logon name mismatch"); } krb5_free_principal(context, p2); return ret; @@ -644,7 +645,7 @@ build_logon_name(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -710,15 +711,15 @@ krb5_pac_verify(krb5_context context, krb5_error_code ret; if (pac->server_checksum == NULL) { - krb5_set_error_string(context, "PAC missing server checksum"); + krb5_set_error_message(context, EINVAL, "PAC missing server checksum"); return EINVAL; } if (pac->privsvr_checksum == NULL) { - krb5_set_error_string(context, "PAC missing kdc checksum"); + krb5_set_error_message(context, EINVAL, "PAC missing kdc checksum"); return EINVAL; } if (pac->logon_name == NULL) { - krb5_set_error_string(context, "PAC missing logon name"); + krb5_set_error_message(context, EINVAL, "PAC missing logon name"); return EINVAL; } @@ -795,7 +796,7 @@ fill_zeros(krb5_context context, krb5_storage *sp, size_t len) l = sizeof(zeros); sret = krb5_storage_write(sp, zeros, l); if (sret <= 0) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } len -= sret; @@ -823,7 +824,7 @@ pac_checksum(krb5_context context, return ret; if (krb5_checksum_is_keyed(context, cktype) == FALSE) { - krb5_set_error_string(context, "PAC checksum type is not keyed"); + krb5_set_error_message(context, EINVAL, "PAC checksum type is not keyed"); return EINVAL; } @@ -868,7 +869,7 @@ _krb5_pac_sign(krb5_context context, ptr = realloc(p->pac, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (p->pac->numbuffers + num - 1))); if (ptr == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } p->pac = ptr; @@ -906,7 +907,7 @@ _krb5_pac_sign(krb5_context context, /* Encode PAC */ sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -914,7 +915,7 @@ _krb5_pac_sign(krb5_context context, spdata = krb5_storage_emem(); if (spdata == NULL) { krb5_storage_free(sp); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE); @@ -953,8 +954,8 @@ _krb5_pac_sign(krb5_context context, sret = krb5_storage_write(spdata, ptr, len); if (sret != len) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } /* XXX if not aligned, fill_zeros */ @@ -985,21 +986,21 @@ _krb5_pac_sign(krb5_context context, /* export PAC */ ret = krb5_storage_to_data(spdata, &d); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_storage_write(sp, d.data, d.length); if (ret != d.length) { krb5_data_free(&d); - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } krb5_data_free(&d); ret = krb5_storage_to_data(sp, &d); if (ret) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } diff --git a/source4/heimdal/lib/krb5/padata.c b/source4/heimdal/lib/krb5/padata.c index b2b70f52e7..9dc3fe69a5 100644 --- a/source4/heimdal/lib/krb5/padata.c +++ b/source4/heimdal/lib/krb5/padata.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: padata.c 15469 2005-06-17 04:28:35Z lha $"); +RCSID("$Id: padata.c 23300 2008-06-23 03:29:22Z lha $"); PA_DATA * krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx) @@ -52,7 +52,7 @@ krb5_padata_add(krb5_context context, METHOD_DATA *md, pa = realloc (md->val, (md->len + 1) * sizeof(*md->val)); if (pa == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } md->val = pa; diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 4a585bff07..1e82971c6e 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 22673 2008-03-10 15:00:05Z lha $"); +RCSID("$Id: pkinit.c 23450 2008-07-27 12:10:10Z lha $"); struct krb5_dh_moduli { char *name; @@ -45,8 +45,6 @@ struct krb5_dh_moduli { #ifdef PKINIT -#include <heim_asn1.h> -#include <rfc2459_asn1.h> #include <cms_asn1.h> #include <pkcs8_asn1.h> #include <pkcs9_asn1.h> @@ -56,22 +54,6 @@ struct krb5_dh_moduli { #include <der.h> -#include <hx509.h> - -enum { - COMPAT_WIN2K = 1, - COMPAT_IETF = 2 -}; - -struct krb5_pk_identity { - hx509_context hx509ctx; - hx509_verify_ctx verify_ctx; - hx509_certs certs; - hx509_certs anchors; - hx509_certs certpool; - hx509_revoke_ctx revokectx; -}; - struct krb5_pk_cert { hx509_cert cert; }; @@ -82,7 +64,7 @@ struct krb5_pk_init_ctx_data { krb5_data *clientDHNonce; struct krb5_dh_moduli **m; hx509_peer_info peer; - int type; + enum krb5_pk_type type; unsigned int require_binding:1; unsigned int require_eku:1; unsigned int require_krbtgt_otherName:1; @@ -91,11 +73,11 @@ struct krb5_pk_init_ctx_data { }; static void -_krb5_pk_copy_error(krb5_context context, - hx509_context hx509ctx, - int hxret, - const char *fmt, - ...) +pk_copy_error(krb5_context context, + hx509_context hx509ctx, + int hxret, + const char *fmt, + ...) __attribute__ ((format (printf, 4, 5))); /* @@ -132,7 +114,7 @@ integer_to_BN(krb5_context context, const char *field, const heim_integer *f) bn = BN_bin2bn((const unsigned char *)f->data, f->length, NULL); if (bn == NULL) { - krb5_set_error_string(context, "PKINIT: parsing BN failed %s", field); + krb5_set_error_message(context, ENOMEM, "PKINIT: parsing BN failed %s", field); return NULL; } BN_set_negative(bn, f->negative); @@ -167,16 +149,16 @@ find_cert(krb5_context context, struct krb5_pk_identity *id, 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); + 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); + pk_copy_error(context, id->hx509ctx, ret, + "Failed cert for finding %s OID", cf[i].type); } return ret; } @@ -196,8 +178,8 @@ create_signature(krb5_context context, ret = hx509_query_alloc(id->hx509ctx, &q); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Allocate query to find signing certificate"); + pk_copy_error(context, id->hx509ctx, ret, + "Allocate query to find signing certificate"); return ret; } @@ -222,8 +204,8 @@ create_signature(krb5_context context, sd_data); hx509_cert_free(cert); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Create CMS signedData"); + pk_copy_error(context, id->hx509ctx, ret, + "Create CMS signedData"); return ret; } @@ -374,7 +356,7 @@ build_auth_pack(krb5_context context, ALLOC(a->pkAuthenticator.paChecksum, 1); if (a->pkAuthenticator.paChecksum == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -524,7 +506,7 @@ pk_mk_padata(krb5_context context, krb5_data_zero(&sd_buf); memset(&content_info, 0, sizeof(content_info)); - if (ctx->type == COMPAT_WIN2K) { + if (ctx->type == PKINIT_WIN2K) { AuthPack_Win2k ap; krb5_timestamp sec; int32_t usec; @@ -554,14 +536,15 @@ pk_mk_padata(krb5_context context, &ap, &size, ret); free_AuthPack_Win2k(&ap); if (ret) { - krb5_set_error_string(context, "AuthPack_Win2k: %d", ret); + krb5_set_error_message(context, ret, "AuthPack_Win2k: %d", + (int)ret); goto out; } if (buf.length != size) krb5_abortx(context, "internal ASN1 encoder error"); oid = oid_id_pkcs7_data(); - } else if (ctx->type == COMPAT_IETF) { + } else if (ctx->type == PKINIT_27) { AuthPack ap; memset(&ap, 0, sizeof(ap)); @@ -575,7 +558,7 @@ pk_mk_padata(krb5_context context, ASN1_MALLOC_ENCODE(AuthPack, buf.data, buf.length, &ap, &size, ret); free_AuthPack(&ap); if (ret) { - krb5_set_error_string(context, "AuthPack: %d", ret); + krb5_set_error_message(context, ret, "AuthPack: %d", (int)ret); goto out; } if (buf.length != size) @@ -594,12 +577,12 @@ pk_mk_padata(krb5_context context, ret = hx509_cms_wrap_ContentInfo(oid_id_pkcs7_signedData(), &sd_buf, &buf); krb5_data_free(&sd_buf); if (ret) { - krb5_set_error_string(context, - "ContentInfo wrapping of signedData failed"); + krb5_set_error_message(context, ret, + "ContentInfo wrapping of signedData failed"); goto out; } - if (ctx->type == COMPAT_WIN2K) { + if (ctx->type == PKINIT_WIN2K) { PA_PK_AS_REQ_Win2k winreq; pa_type = KRB5_PADATA_PK_AS_REQ_WIN; @@ -612,7 +595,7 @@ pk_mk_padata(krb5_context context, &winreq, &size, ret); free_PA_PK_AS_REQ_Win2k(&winreq); - } else if (ctx->type == COMPAT_IETF) { + } else if (ctx->type == PKINIT_27) { PA_PK_AS_REQ req; pa_type = KRB5_PADATA_PK_AS_REQ; @@ -624,14 +607,15 @@ pk_mk_padata(krb5_context context, req.trustedCertifiers = calloc(1, sizeof(*req.trustedCertifiers)); if (req.trustedCertifiers == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); free_PA_PK_AS_REQ(&req); goto out; } ret = build_edi(context, ctx->id->hx509ctx, ctx->id->anchors, req.trustedCertifiers); if (ret) { - krb5_set_error_string(context, "pk-init: failed to build trustedCertifiers"); + krb5_set_error_message(context, ret, "pk-init: failed to build trustedCertifiers"); free_PA_PK_AS_REQ(&req); goto out; } @@ -646,7 +630,7 @@ pk_mk_padata(krb5_context context, } else krb5_abortx(context, "internal pkinit error"); if (ret) { - krb5_set_error_string(context, "PA-PK-AS-REQ %d", ret); + krb5_set_error_message(context, ret, "PA-PK-AS-REQ %d", (int)ret); goto out; } if (buf.length != size) @@ -656,10 +640,10 @@ pk_mk_padata(krb5_context context, if (ret) free(buf.data); - if (ret == 0 && ctx->type == COMPAT_WIN2K) + if (ret == 0 && ctx->type == PKINIT_WIN2K) krb5_padata_add(context, md, KRB5_PADATA_PK_AS_09_BINDING, NULL, 0); -out: + out: free_ContentInfo(&content_info); return ret; @@ -691,9 +675,9 @@ _krb5_pk_mk_padata(krb5_context context, req_body->realm, "pkinit_win2k_require_binding", NULL); - ctx->type = COMPAT_WIN2K; + ctx->type = PKINIT_WIN2K; } else - ctx->type = COMPAT_IETF; + ctx->type = PKINIT_27; ctx->require_eku = krb5_config_get_bool_default(context, NULL, @@ -753,8 +737,8 @@ _krb5_pk_verify_sign(krb5_context context, content, &signer_certs); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "CMS verify signed failed"); + pk_copy_error(context, id->hx509ctx, ret, + "CMS verify signed failed"); return ret; } @@ -767,12 +751,12 @@ _krb5_pk_verify_sign(krb5_context context, ret = hx509_get_one_cert(id->hx509ctx, signer_certs, &(*signer)->cert); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to get on of the signer certs"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to get on of the signer certs"); goto out; } -out: + out: hx509_certs_free(&signer_certs); if (ret) { if (*signer) { @@ -800,29 +784,28 @@ get_reply_key_win(krb5_context context, &key_pack, &size); if (ret) { - krb5_set_error_string(context, "PKINIT decoding reply key failed"); + krb5_set_error_message(context, ret, "PKINIT decoding reply key failed"); free_ReplyKeyPack_Win2k(&key_pack); return ret; } if (key_pack.nonce != nonce) { - krb5_set_error_string(context, "PKINIT enckey nonce is wrong"); + krb5_set_error_message(context, ret, "PKINIT enckey nonce is wrong"); free_ReplyKeyPack_Win2k(&key_pack); return KRB5KRB_AP_ERR_MODIFIED; } *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "PKINIT failed allocating reply key"); free_ReplyKeyPack_Win2k(&key_pack); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_EncryptionKey(&key_pack.replyKey, *key); free_ReplyKeyPack_Win2k(&key_pack); if (ret) { - krb5_set_error_string(context, "PKINIT failed copying reply key"); + krb5_set_error_message(context, ret, "PKINIT failed copying reply key"); free(*key); *key = NULL; } @@ -845,7 +828,7 @@ get_reply_key(krb5_context context, &key_pack, &size); if (ret) { - krb5_set_error_string(context, "PKINIT decoding reply key failed"); + krb5_set_error_message(context, ret, "PKINIT decoding reply key failed"); free_ReplyKeyPack(&key_pack); return ret; } @@ -876,16 +859,15 @@ get_reply_key(krb5_context context, *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "PKINIT failed allocating reply key"); free_ReplyKeyPack(&key_pack); - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = copy_EncryptionKey(&key_pack.replyKey, *key); free_ReplyKeyPack(&key_pack); if (ret) { - krb5_set_error_string(context, "PKINIT failed copying reply key"); + krb5_set_error_message(context, ret, "PKINIT failed copying reply key"); free(*key); *key = NULL; } @@ -907,7 +889,7 @@ pk_verify_host(krb5_context context, ret = hx509_cert_check_eku(ctx->id->hx509ctx, host->cert, oid_id_pkkdcekuoid(), 0); if (ret) { - krb5_set_error_string(context, "No PK-INIT KDC EKU in kdc certificate"); + krb5_set_error_message(context, ret, "No PK-INIT KDC EKU in kdc certificate"); return ret; } } @@ -920,8 +902,8 @@ pk_verify_host(krb5_context context, oid_id_pkinit_san(), &list); if (ret) { - krb5_set_error_string(context, "Failed to find the PK-INIT " - "subjectAltName in the KDC certificate"); + krb5_set_error_message(context, ret, "Failed to find the PK-INIT " + "subjectAltName in the KDC certificate"); return ret; } @@ -934,8 +916,8 @@ pk_verify_host(krb5_context context, &r, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode the PK-INIT " - "subjectAltName in the KDC certificate"); + krb5_set_error_message(context, ret, "Failed to decode the PK-INIT " + "subjectAltName in the KDC certificate"); break; } @@ -944,11 +926,11 @@ pk_verify_host(krb5_context context, strcmp(r.principalName.name_string.val[0], KRB5_TGS_NAME) != 0 || strcmp(r.principalName.name_string.val[1], realm) != 0 || strcmp(r.realm, realm) != 0) - { - krb5_set_error_string(context, "KDC have wrong realm name in " - "the certificate"); - ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; - } + { + ret = KRB5_KDC_ERR_INVALID_CERTIFICATE; + krb5_set_error_message(context, ret, "KDC have wrong realm name in " + "the certificate"); + } free_KRB5PrincipalName(&r); if (ret) @@ -967,8 +949,8 @@ pk_verify_host(krb5_context context, hi->ai->ai_addr, hi->ai->ai_addrlen); if (ret) - krb5_set_error_string(context, "Address mismatch in " - "the KDC certificate"); + krb5_set_error_message(context, ret, "Address mismatch in " + "the KDC certificate"); } return ret; } @@ -993,7 +975,7 @@ pk_rd_pa_reply_enckey(krb5_context context, heim_oid contentType = { 0, NULL }; if (der_heim_oid_cmp(oid_id_pkcs7_envelopedData(), dataType)) { - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type"); return EINVAL; } @@ -1003,11 +985,12 @@ pk_rd_pa_reply_enckey(krb5_context context, indata->data, indata->length, NULL, + 0, &contentType, &content); if (ret) { - _krb5_pk_copy_error(context, ctx->id->hx509ctx, ret, - "Failed to unenvelope CMS data in PK-INIT reply"); + pk_copy_error(context, ctx->id->hx509ctx, ret, + "Failed to unenvelope CMS data in PK-INIT reply"); return ret; } der_free_oid(&contentType); @@ -1031,14 +1014,14 @@ pk_rd_pa_reply_enckey(krb5_context context, #endif /* win2k uses ContentInfo */ - if (type == COMPAT_WIN2K) { + if (type == PKINIT_WIN2K) { heim_oid type; heim_octet_string out; ret = hx509_cms_unwrap_ContentInfo(&content, &type, &out, NULL); if (der_heim_oid_cmp(&type, oid_id_pkcs7_signedData())) { ret = EINVAL; /* XXX */ - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, ret, "PKINIT: Invalid content type"); der_free_oid(&type); der_free_octet_string(&out); goto out; @@ -1048,7 +1031,7 @@ pk_rd_pa_reply_enckey(krb5_context context, ret = krb5_data_copy(&content, out.data, out.length); der_free_octet_string(&out); if (ret) { - krb5_set_error_string(context, "PKINIT: out of memory"); + krb5_set_error_message(context, ret, "PKINIT: out of memory"); goto out; } } @@ -1070,28 +1053,28 @@ pk_rd_pa_reply_enckey(krb5_context context, } #if 0 - if (type == COMPAT_WIN2K) { + if (type == PKINIT_WIN2K) { if (der_heim_oid_cmp(&contentType, oid_id_pkcs7_data()) != 0) { - krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid"); goto out; } } else { if (der_heim_oid_cmp(&contentType, oid_id_pkrkeydata()) != 0) { - krb5_set_error_string(context, "PKINIT: reply key, wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "PKINIT: reply key, wrong oid"); goto out; } } #endif switch(type) { - case COMPAT_WIN2K: + case PKINIT_WIN2K: ret = get_reply_key(context, &content, req_buffer, key); if (ret != 0 && ctx->require_binding == 0) ret = get_reply_key_win(context, &content, nonce, key); break; - case COMPAT_IETF: + case PKINIT_27: ret = get_reply_key(context, &content, req_buffer, key); break; } @@ -1137,7 +1120,7 @@ pk_rd_pa_reply_dh(krb5_context context, memset(&kdc_dh_info, 0, sizeof(kdc_dh_info)); if (der_heim_oid_cmp(oid_id_pkcs7_signedData(), dataType)) { - krb5_set_error_string(context, "PKINIT: Invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: Invalid content type"); return EINVAL; } @@ -1157,8 +1140,8 @@ pk_rd_pa_reply_dh(krb5_context context, goto out; if (der_heim_oid_cmp(&contentType, oid_id_pkdhkeydata())) { - krb5_set_error_string(context, "pkinit - dh reply contains wrong oid"); ret = KRB5KRB_AP_ERR_MSG_TYPE; + krb5_set_error_message(context, ret, "pkinit - dh reply contains wrong oid"); goto out; } @@ -1168,35 +1151,35 @@ pk_rd_pa_reply_dh(krb5_context context, &size); if (ret) { - krb5_set_error_string(context, "pkinit - " - "failed to decode KDC DH Key Info"); + krb5_set_error_message(context, ret, "pkinit - " + "failed to decode KDC DH Key Info"); goto out; } if (kdc_dh_info.nonce != nonce) { - krb5_set_error_string(context, "PKINIT: DH nonce is wrong"); ret = KRB5KRB_AP_ERR_MODIFIED; + krb5_set_error_message(context, ret, "PKINIT: DH nonce is wrong"); goto out; } if (kdc_dh_info.dhKeyExpiration) { if (k_n == NULL) { - krb5_set_error_string(context, "pkinit; got key expiration " - "without server nonce"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit; got key expiration " + "without server nonce"); goto out; } if (c_n == NULL) { - krb5_set_error_string(context, "pkinit; got DH reuse but no " - "client nonce"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit; got DH reuse but no " + "client nonce"); goto out; } } else { if (k_n) { - krb5_set_error_string(context, "pkinit: got server nonce " - "without key expiration"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, "pkinit: got server nonce " + "without key expiration"); goto out; } c_n = NULL; @@ -1210,15 +1193,15 @@ pk_rd_pa_reply_dh(krb5_context context, DHPublicKey k; ret = decode_DHPublicKey(p, size, &k, NULL); if (ret) { - krb5_set_error_string(context, "pkinit: can't decode " - "without key expiration"); + krb5_set_error_message(context, ret, "pkinit: can't decode " + "without key expiration"); goto out; } kdc_dh_pubkey = integer_to_BN(context, "DHPublicKey", &k); free_DHPublicKey(&k); if (kdc_dh_pubkey == NULL) { - ret = KRB5KRB_ERR_GENERIC; + ret = ENOMEM; goto out; } } @@ -1230,8 +1213,8 @@ pk_rd_pa_reply_dh(krb5_context context, dh_gen_key = malloc(size); if (dh_gen_key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } memset(dh_gen_key, 0, size - dh_gen_keylen); @@ -1239,16 +1222,16 @@ pk_rd_pa_reply_dh(krb5_context context, dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen), kdc_dh_pubkey, ctx->dh); if (dh_gen_keylen == -1) { - krb5_set_error_string(context, - "PKINIT: Can't compute Diffie-Hellman key"); ret = KRB5KRB_ERR_GENERIC; + krb5_set_error_message(context, ret, + "PKINIT: Can't compute Diffie-Hellman key"); goto out; } *key = malloc (sizeof (**key)); if (*key == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -1258,8 +1241,8 @@ pk_rd_pa_reply_dh(krb5_context context, c_n, k_n, *key); if (ret) { - krb5_set_error_string(context, - "PKINIT: can't create key from DH key"); + krb5_set_error_message(context, ret, + "PKINIT: can't create key from DH key"); free(*key); *key = NULL; goto out; @@ -1298,13 +1281,13 @@ _krb5_pk_rd_pa_reply(krb5_context context, size_t size; /* Check for IETF PK-INIT first */ - if (ctx->type == COMPAT_IETF) { + if (ctx->type == PKINIT_27) { PA_PK_AS_REP rep; heim_octet_string os, data; heim_oid oid; if (pa->padata_type != KRB5_PADATA_PK_AS_REP) { - krb5_set_error_string(context, "PKINIT: wrong padata recv"); + krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv"); return EINVAL; } @@ -1313,7 +1296,7 @@ _krb5_pk_rd_pa_reply(krb5_context context, &rep, &size); if (ret) { - krb5_set_error_string(context, "Failed to decode pkinit AS rep"); + krb5_set_error_message(context, ret, "Failed to decode pkinit AS rep"); return ret; } @@ -1326,15 +1309,15 @@ _krb5_pk_rd_pa_reply(krb5_context context, break; default: free_PA_PK_AS_REP(&rep); - krb5_set_error_string(context, "PKINIT: -27 reply " - "invalid content type"); + krb5_set_error_message(context, EINVAL, "PKINIT: -27 reply " + "invalid content type"); return EINVAL; } ret = hx509_cms_unwrap_ContentInfo(&os, &oid, &data, NULL); if (ret) { free_PA_PK_AS_REP(&rep); - krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); + krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI"); return ret; } @@ -1346,7 +1329,7 @@ _krb5_pk_rd_pa_reply(krb5_context context, nonce, pa, key); break; case choice_PA_PK_AS_REP_encKeyPack: - ret = pk_rd_pa_reply_enckey(context, COMPAT_IETF, &data, &oid, realm, + ret = pk_rd_pa_reply_enckey(context, PKINIT_27, &data, &oid, realm, ctx, etype, hi, nonce, req_buffer, pa, key); break; default: @@ -1356,14 +1339,14 @@ _krb5_pk_rd_pa_reply(krb5_context context, der_free_oid(&oid); free_PA_PK_AS_REP(&rep); - } else if (ctx->type == COMPAT_WIN2K) { + } else if (ctx->type == PKINIT_WIN2K) { PA_PK_AS_REP_Win2k w2krep; /* Check for Windows encoding of the AS-REP pa data */ #if 0 /* should this be ? */ if (pa->padata_type != KRB5_PADATA_PK_AS_REP) { - krb5_set_error_string(context, "PKINIT: wrong padata recv"); + krb5_set_error_message(context, EINVAL, "PKINIT: wrong padata recv"); return EINVAL; } #endif @@ -1375,8 +1358,8 @@ _krb5_pk_rd_pa_reply(krb5_context context, &w2krep, &size); if (ret) { - krb5_set_error_string(context, "PKINIT: Failed decoding windows " - "pkinit reply %d", ret); + krb5_set_error_message(context, ret, "PKINIT: Failed decoding windows " + "pkinit reply %d", (int)ret); return ret; } @@ -1391,11 +1374,11 @@ _krb5_pk_rd_pa_reply(krb5_context context, &oid, &data, NULL); free_PA_PK_AS_REP_Win2k(&w2krep); if (ret) { - krb5_set_error_string(context, "PKINIT: failed to unwrap CI"); + krb5_set_error_message(context, ret, "PKINIT: failed to unwrap CI"); return ret; } - ret = pk_rd_pa_reply_enckey(context, COMPAT_WIN2K, &data, &oid, realm, + ret = pk_rd_pa_reply_enckey(context, PKINIT_WIN2K, &data, &oid, realm, ctx, etype, hi, nonce, req_buffer, pa, key); der_free_octet_string(&data); der_free_oid(&oid); @@ -1404,15 +1387,15 @@ _krb5_pk_rd_pa_reply(krb5_context context, } default: free_PA_PK_AS_REP_Win2k(&w2krep); - krb5_set_error_string(context, "PKINIT: win2k reply invalid " - "content type"); ret = EINVAL; + krb5_set_error_message(context, ret, "PKINIT: win2k reply invalid " + "content type"); break; } } else { - krb5_set_error_string(context, "PKINIT: unknown reply type"); ret = EINVAL; + krb5_set_error_message(context, ret, "PKINIT: unknown reply type"); } return ret; @@ -1486,13 +1469,14 @@ _krb5_pk_load_id(krb5_context context, *ret_id = NULL; if (anchor_id == NULL) { - krb5_set_error_string(context, "PKINIT: No anchor given"); + krb5_set_error_message(context, HEIM_PKINIT_NO_VALID_CA, + "PKINIT: No anchor given"); return HEIM_PKINIT_NO_VALID_CA; } if (user_id == NULL) { - krb5_set_error_string(context, - "PKINIT: No user certificate given"); + krb5_set_error_message(context, HEIM_PKINIT_NO_PRIVATE_KEY, + "PKINIT: No user certificate given"); return HEIM_PKINIT_NO_PRIVATE_KEY; } @@ -1500,7 +1484,7 @@ _krb5_pk_load_id(krb5_context context, id = calloc(1, sizeof(*id)); if (id == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1524,23 +1508,23 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_certs_init(id->hx509ctx, user_id, 0, lock, &id->certs); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init cert certs"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init cert certs"); goto out; } ret = hx509_certs_init(id->hx509ctx, anchor_id, 0, NULL, &id->anchors); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init anchors"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init anchors"); goto out; } ret = hx509_certs_init(id->hx509ctx, "MEMORY:pkinit-cert-chain", 0, NULL, &id->certpool); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to init chain"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to init chain"); goto out; } @@ -1548,9 +1532,9 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_certs_append(id->hx509ctx, id->certpool, NULL, *chain_list); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed to laod chain %s", - *chain_list); + pk_copy_error(context, id->hx509ctx, ret, + "Failed to laod chain %s", + *chain_list); goto out; } chain_list++; @@ -1559,8 +1543,8 @@ _krb5_pk_load_id(krb5_context context, if (revoke_list) { ret = hx509_revoke_init(id->hx509ctx, &id->revokectx); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed init revoke list"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed init revoke list"); goto out; } @@ -1569,8 +1553,8 @@ _krb5_pk_load_id(krb5_context context, id->revokectx, *revoke_list); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed load revoke list"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed load revoke list"); goto out; } revoke_list++; @@ -1580,15 +1564,15 @@ _krb5_pk_load_id(krb5_context context, ret = hx509_verify_init_ctx(id->hx509ctx, &id->verify_ctx); if (ret) { - _krb5_pk_copy_error(context, id->hx509ctx, ret, - "Failed init verify context"); + pk_copy_error(context, id->hx509ctx, ret, + "Failed init verify context"); goto out; } hx509_verify_attach_anchors(id->verify_ctx, id->anchors); hx509_verify_attach_revoke(id->verify_ctx, id->revokectx); -out: + out: if (ret) { hx509_verify_destroy_ctx(id->verify_ctx); hx509_certs_free(&id->certs); @@ -1622,10 +1606,10 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits, break; } if (moduli[i] == NULL) { - krb5_set_error_string(context, - "Did not find a DH group parameter " - "matching requirement of %lu bits", - bits); + krb5_set_error_message(context, EINVAL, + "Did not find a DH group parameter " + "matching requirement of %lu bits", + bits); return EINVAL; } m = moduli[i]; @@ -1644,6 +1628,39 @@ select_dh_group(krb5_context context, DH *dh, unsigned long bits, return 0; } +/* + * + */ + +static void +pk_copy_error(krb5_context context, + hx509_context hx509ctx, + int hxret, + const char *fmt, + ...) +{ + va_list va; + char *s, *f; + + va_start(va, fmt); + vasprintf(&f, fmt, va); + va_end(va); + if (f == NULL) { + krb5_clear_error_string(context); + return; + } + + s = hx509_get_error_string(hx509ctx, hxret); + if (s == NULL) { + krb5_clear_error_string(context); + free(f); + return; + } + krb5_set_error_message(context, hxret, "%s: %s", f, s); + free(s); + free(f); +} + #endif /* PKINIT */ static int @@ -1654,15 +1671,15 @@ parse_integer(krb5_context context, char **p, const char *file, int lineno, char *p1; p1 = strsep(p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing %s on line %d", - file, name, lineno); + krb5_set_error_message(context, EINVAL, "moduli file %s missing %s on line %d", + file, name, lineno); return EINVAL; } ret = der_parse_hex_heim_integer(p1, integer); if (ret) { - krb5_set_error_string(context, "moduli file %s failed parsing %s " - "on line %d", - file, name, lineno); + krb5_set_error_message(context, ret, "moduli file %s failed parsing %s " + "on line %d", + file, name, lineno); return ret; } @@ -1684,7 +1701,7 @@ _krb5_parse_moduli_line(krb5_context context, m1 = calloc(1, sizeof(*m1)); if (m1 == NULL) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1696,28 +1713,28 @@ _krb5_parse_moduli_line(krb5_context context, p1 = strsep(&p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing name " - "on line %d", file, lineno); + krb5_set_error_message(context, ret, "moduli file %s missing name " + "on line %d", file, lineno); goto out; } m1->name = strdup(p1); if (p1 == NULL) { - krb5_set_error_string(context, "malloc - out of memeory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc - out of memeory"); goto out; } p1 = strsep(&p, " \t"); if (p1 == NULL) { - krb5_set_error_string(context, "moduli file %s missing bits on line %d", - file, lineno); + krb5_set_error_message(context, ret, "moduli file %s missing bits on line %d", + file, lineno); goto out; } m1->bits = atoi(p1); if (m1->bits == 0) { - krb5_set_error_string(context, "moduli file %s have un-parsable " - "bits on line %d", file, lineno); + krb5_set_error_message(context, ret, "moduli file %s have un-parsable " + "bits on line %d", file, lineno); goto out; } @@ -1734,7 +1751,7 @@ _krb5_parse_moduli_line(krb5_context context, *m = m1; return 0; -out: + out: free(m1->name); der_free_heim_integer(&m1->p); der_free_heim_integer(&m1->g); @@ -1826,7 +1843,7 @@ _krb5_parse_moduli(krb5_context context, const char *file, m = calloc(1, sizeof(m[0]) * 3); if (m == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -1855,6 +1872,7 @@ _krb5_parse_moduli(krb5_context context, const char *file, *moduli = m; return 0; } + rk_cloexec_file(f); while(fgets(buf, sizeof(buf), f) != NULL) { struct krb5_dh_moduli *element; @@ -1864,8 +1882,8 @@ _krb5_parse_moduli(krb5_context context, const char *file, m2 = realloc(m, (n + 2) * sizeof(m[0])); if (m2 == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); _krb5_free_moduli(m); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } m = m2; @@ -1903,19 +1921,23 @@ _krb5_dh_group_ok(krb5_context context, unsigned long bits, if (der_heim_integer_cmp(&moduli[i]->g, g) == 0 && der_heim_integer_cmp(&moduli[i]->p, p) == 0 && (q == NULL || der_heim_integer_cmp(&moduli[i]->q, q) == 0)) - { - if (bits && bits > moduli[i]->bits) { - krb5_set_error_string(context, "PKINIT: DH group parameter %s " - "no accepted, not enough bits generated", - moduli[i]->name); - return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + { + if (bits && bits > moduli[i]->bits) { + krb5_set_error_message(context, + KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, + "PKINIT: DH group parameter %s " + "no accepted, not enough bits generated", + moduli[i]->name); + return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; + } + if (name) + *name = strdup(moduli[i]->name); + return 0; } - if (name) - *name = strdup(moduli[i]->name); - return 0; - } } - krb5_set_error_string(context, "PKINIT: DH group parameter no ok"); + krb5_set_error_message(context, + KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED, + "PKINIT: DH group parameter no ok"); return KRB5_KDC_ERR_DH_KEY_PARAMETERS_NOT_ACCEPTED; } @@ -1930,7 +1952,7 @@ _krb5_get_init_creds_opt_free_pkinit(krb5_get_init_creds_opt *opt) ctx = opt->opt_private->pk_init_ctx; if (ctx->dh) DH_free(ctx->dh); - ctx->dh = NULL; + ctx->dh = NULL; if (ctx->id) { hx509_verify_destroy_ctx(ctx->id->verify_ctx); hx509_certs_free(&ctx->id->certs); @@ -1970,14 +1992,14 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, char *anchors = NULL; if (opt->opt_private == NULL) { - krb5_set_error_string(context, "PKINIT: on non extendable opt"); + krb5_set_error_message(context, EINVAL, "PKINIT: on non extendable opt"); return EINVAL; } opt->opt_private->pk_init_ctx = calloc(1, sizeof(*opt->opt_private->pk_init_ctx)); if (opt->opt_private->pk_init_ctx == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } opt->opt_private->pk_init_ctx->dh = NULL; @@ -2047,8 +2069,8 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, opt->opt_private->pk_init_ctx->dh = DH_new(); if (opt->opt_private->pk_init_ctx->dh == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); _krb5_get_init_creds_opt_free_pkinit(opt); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -2061,48 +2083,15 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, } if (DH_generate_key(opt->opt_private->pk_init_ctx->dh) != 1) { - krb5_set_error_string(context, "pkinit: failed to generate DH key"); _krb5_get_init_creds_opt_free_pkinit(opt); + krb5_set_error_message(context, ENOMEM, "pkinit: failed to generate DH key"); return ENOMEM; } } return 0; #else - krb5_set_error_string(context, "no support for PKINIT compiled in"); + krb5_set_error_message(context, EINVAL, "no support for PKINIT compiled in"); return EINVAL; #endif } - -/* - * - */ - -static void -_krb5_pk_copy_error(krb5_context context, - hx509_context hx509ctx, - int hxret, - const char *fmt, - ...) -{ - va_list va; - char *s, *f; - - va_start(va, fmt); - vasprintf(&f, fmt, va); - va_end(va); - if (f == NULL) { - krb5_clear_error_string(context); - return; - } - - s = hx509_get_error_string(hx509ctx, hxret); - if (s == NULL) { - krb5_clear_error_string(context); - free(f); - return; - } - krb5_set_error_string(context, "%s: %s", f, s); - free(s); - free(f); -} diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index bae28496aa..8dda27fa59 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 22033 2007-11-10 10:39:47Z lha $"); +RCSID("$Id: plugin.c 23451 2008-07-27 12:10:30Z lha $"); #ifdef HAVE_DLFCN_H #include <dlfcn.h> #endif @@ -87,7 +87,7 @@ loadlib(krb5_context context, { *e = calloc(1, sizeof(**e)); if (*e == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -99,8 +99,8 @@ loadlib(krb5_context context, if ((*e)->dsohandle == NULL) { free(*e); *e = NULL; - krb5_set_error_string(context, "Failed to load %s: %s", - lib, dlerror()); + krb5_set_error_message(context, ENOMEM, "Failed to load %s: %s", + lib, dlerror()); return ENOMEM; } @@ -139,14 +139,14 @@ krb5_plugin_register(krb5_context context, e = calloc(1, sizeof(*e)); if (e == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e->type = type; e->name = strdup(name); if (e->name == NULL) { free(e); - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } e->symbol = symbol; @@ -185,8 +185,8 @@ _krb5_plugin_find(krb5_context context, e = calloc(1, sizeof(*e)); if (e == NULL) { HEIMDAL_MUTEX_unlock(&plugin_mutex); - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } e->symbol = p->symbol; @@ -210,12 +210,13 @@ _krb5_plugin_find(krb5_context context, d = opendir(*di); if (d == NULL) continue; + rk_cloexec(dirfd(d)); while ((entry = readdir(d)) != NULL) { asprintf(&path, "%s/%s", *di, entry->d_name); if (path == NULL) { - krb5_set_error_string(context, "out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = loadlib(context, type, name, path, &e); @@ -233,7 +234,7 @@ _krb5_plugin_find(krb5_context context, #endif /* HAVE_DLOPEN */ if (*list == NULL) { - krb5_set_error_string(context, "Did not find a plugin for %s", name); + krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name); return ENOENT; } diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index cdad477115..0d6d72dbcf 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -57,7 +57,7 @@ host/admin@H5L.ORG #include <fnmatch.h> #include "resolve.h" -RCSID("$Id: principal.c 22549 2008-01-29 09:37:25Z lha $"); +RCSID("$Id: principal.c 23316 2008-06-23 04:32:32Z lha $"); #define princ_num_comp(P) ((P)->name.name_string.len) #define princ_type(P) ((P)->name.name_type) @@ -149,8 +149,9 @@ krb5_parse_name_flags(krb5_context context, #define RFLAGS (KRB5_PRINCIPAL_PARSE_NO_REALM|KRB5_PRINCIPAL_PARSE_MUST_REALM) if ((flags & RFLAGS) == RFLAGS) { - krb5_set_error_string(context, "Can't require both realm and " - "no realm at the same time"); + krb5_set_error_message(context, KRB5_ERR_NO_SERVICE, + "Can't require both realm and " + "no realm at the same time"); return KRB5_ERR_NO_SERVICE; } #undef RFLAGS @@ -163,7 +164,7 @@ krb5_parse_name_flags(krb5_context context, for(p = name; *p; p++){ if(*p=='\\'){ if(!p[1]) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "trailing \\ in principal name"); return KRB5_PARSE_MALFORMED; } @@ -176,7 +177,7 @@ krb5_parse_name_flags(krb5_context context, } comp = calloc(ncomp, sizeof(*comp)); if (comp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -184,7 +185,7 @@ krb5_parse_name_flags(krb5_context context, p = start = q = s = strdup(name); if (start == NULL) { free (comp); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } while(*p){ @@ -200,9 +201,9 @@ krb5_parse_name_flags(krb5_context context, else if(c == '0') c = '\0'; else if(c == '\0') { - krb5_set_error_string (context, - "trailing \\ in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "trailing \\ in principal name"); goto exit; } }else if(enterprise && first_at) { @@ -210,15 +211,15 @@ krb5_parse_name_flags(krb5_context context, first_at = 0; }else if((c == '/' && !enterprise) || c == '@'){ if(got_realm){ - krb5_set_error_string (context, - "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "part after realm in principal name"); goto exit; }else{ comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(comp[n], start, q - start); @@ -231,33 +232,33 @@ krb5_parse_name_flags(krb5_context context, continue; } if(got_realm && (c == ':' || c == '/' || c == '\0')) { - krb5_set_error_string (context, - "part after realm in principal name"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, + "part after realm in principal name"); goto exit; } *q++ = c; } if(got_realm){ if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { - krb5_set_error_string (context, "realm found in 'short' principal " - "expected to be without one"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "realm found in 'short' principal " + "expected to be without one"); goto exit; } realm = malloc(q - start + 1); if (realm == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(realm, start, q - start); realm[q - start] = 0; }else{ if (flags & KRB5_PRINCIPAL_PARSE_MUST_REALM) { - krb5_set_error_string (context, "realm NOT found in principal " - "expected to be with one"); ret = KRB5_PARSE_MALFORMED; + krb5_set_error_message(context, ret, "realm NOT found in principal " + "expected to be with one"); goto exit; } else if (flags & KRB5_PRINCIPAL_PARSE_NO_REALM) { realm = NULL; @@ -269,8 +270,8 @@ krb5_parse_name_flags(krb5_context context, comp[n] = malloc(q - start + 1); if (comp[n] == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } memcpy(comp[n], start, q - start); @@ -279,8 +280,8 @@ krb5_parse_name_flags(krb5_context context, } *principal = malloc(sizeof(**principal)); if (*principal == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); goto exit; } if (enterprise) @@ -350,7 +351,8 @@ unparse_name_fixed(krb5_context context, int display = (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) != 0; if (!no_realm && princ_realm(principal) == NULL) { - krb5_set_error_string(context, "Realm missing from principal, " + krb5_set_error_message(context, ERANGE, + "Realm missing from principal, " "can't unparse"); return ERANGE; } @@ -360,7 +362,7 @@ unparse_name_fixed(krb5_context context, add_char(name, idx, len, '/'); idx = quote_string(princ_ncomp(principal, i), name, idx, len, display); if(idx == len) { - krb5_set_error_string(context, "Out of space printing principal"); + krb5_set_error_message(context, ERANGE, "Out of space printing principal"); return ERANGE; } } @@ -379,8 +381,8 @@ unparse_name_fixed(krb5_context context, add_char(name, idx, len, '@'); idx = quote_string(princ_realm(principal), name, idx, len, display); if(idx == len) { - krb5_set_error_string(context, - "Out of space printing realm of principal"); + krb5_set_error_message(context, ERANGE, + "Out of space printing realm of principal"); return ERANGE; } } @@ -446,7 +448,7 @@ unparse_name(krb5_context context, len++; /* '\0' */ *name = malloc(len); if(*name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } ret = unparse_name_fixed(context, principal, *name, len, flags); @@ -511,6 +513,22 @@ krb5_princ_set_realm(krb5_context context, princ_realm(principal) = *realm; } +krb5_error_code KRB5_LIB_FUNCTION +krb5_principal_set_realm(krb5_context context, + krb5_principal principal, + krb5_const_realm realm) +{ + if (princ_realm(principal)) + free(princ_realm(principal)); + + princ_realm(principal) = strdup(realm); + if (princ_realm(principal) == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + return 0; +} + krb5_error_code KRB5_LIB_FUNCTION krb5_build_principal(krb5_context context, @@ -537,13 +555,13 @@ append_component(krb5_context context, krb5_principal p, tmp = realloc(princ_comp(p), (len + 1) * sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } princ_comp(p) = tmp; princ_ncomp(p, len) = malloc(comp_len + 1); if (princ_ncomp(p, len) == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy (princ_ncomp(p, len), comp, comp_len); @@ -591,7 +609,7 @@ build_principal(krb5_context context, p = calloc(1, sizeof(*p)); if (p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } princ_type(p) = KRB5_NT_PRINCIPAL; @@ -599,7 +617,7 @@ build_principal(krb5_context context, princ_realm(p) = strdup(realm); if(p->realm == NULL){ free(p); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -675,12 +693,12 @@ krb5_copy_principal(krb5_context context, { krb5_principal p = malloc(sizeof(*p)); if (p == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if(copy_Principal(inprinc, p)) { free(p); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *outprinc = p; @@ -706,6 +724,22 @@ krb5_principal_compare_any_realm(krb5_context context, return TRUE; } +krb5_boolean KRB5_LIB_FUNCTION +_krb5_principal_compare_PrincipalName(krb5_context context, + krb5_const_principal princ1, + PrincipalName *princ2) +{ + int i; + if (princ_num_comp(princ1) != princ2->name_string.len) + return FALSE; + for(i = 0; i < princ_num_comp(princ1); i++){ + if(strcmp(princ_ncomp(princ1, i), princ2->name_string.val[i]) != 0) + return FALSE; + } + return TRUE; +} + + /* * return TRUE iff princ1 == princ2 */ @@ -909,7 +943,7 @@ krb5_425_conv_principal_ext2(krb5_context context, #endif if (passed) { if (inst == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlwr(inst); @@ -1160,7 +1194,7 @@ krb5_524_conv_principal(krb5_context context, i = principal->name.name_string.val[1]; break; default: - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "cannot convert a %d component principal", principal->name.name_string.len); return KRB5_PARSE_MALFORMED; @@ -1186,17 +1220,17 @@ krb5_524_conv_principal(krb5_context context, } if (strlcpy (name, n, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long name component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (instance, i, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long instance component to convert"); return KRB5_PARSE_MALFORMED; } if (strlcpy (realm, r, aname_sz) >= aname_sz) { - krb5_set_error_string (context, + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, "too long realm component to convert"); return KRB5_PARSE_MALFORMED; } @@ -1219,8 +1253,9 @@ krb5_sname_to_principal (krb5_context context, char **realms, *host = NULL; if(type != KRB5_NT_SRV_HST && type != KRB5_NT_UNKNOWN) { - krb5_set_error_string (context, "unsupported name type %d", - type); + krb5_set_error_message(context, KRB5_SNAME_UNSUPP_NAMETYPE, + "unsupported name type %d", + (int)type); return KRB5_SNAME_UNSUPP_NAMETYPE; } if(hostname == NULL) { @@ -1280,6 +1315,7 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) return 0; } } - krb5_set_error_string(context, "Failed to find name type %s", str); + krb5_set_error_message(context, KRB5_PARSE_MALFORMED, + "Failed to find name type %s", str); return KRB5_PARSE_MALFORMED; } diff --git a/source4/heimdal/lib/krb5/rd_cred.c b/source4/heimdal/lib/krb5/rd_cred.c index c3f732201f..26aa3f2d79 100644 --- a/source4/heimdal/lib/krb5/rd_cred.c +++ b/source4/heimdal/lib/krb5/rd_cred.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_cred.c 20304 2007-04-11 11:15:05Z lha $"); +RCSID("$Id: rd_cred.c 23316 2008-06-23 04:32:32Z lha $"); static krb5_error_code compare_addrs(krb5_context context, @@ -49,7 +49,8 @@ compare_addrs(krb5_context context, krb5_print_address (a, a_str, sizeof(a_str), &len); krb5_print_address (b, b_str, sizeof(b_str), &len); - krb5_set_error_string(context, "%s: %s != %s", message, b_str, a_str); + krb5_set_error_message(context, KRB5KRB_AP_ERR_BADADDR, + "%s: %s != %s", message, b_str, a_str); return KRB5KRB_AP_ERR_BADADDR; } @@ -244,7 +245,7 @@ krb5_rd_cred(krb5_context context, if (*ret_creds == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } @@ -255,7 +256,7 @@ krb5_rd_cred(krb5_context context, creds = calloc(1, sizeof(*creds)); if(creds == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } diff --git a/source4/heimdal/lib/krb5/rd_error.c b/source4/heimdal/lib/krb5/rd_error.c index e7646467af..9e50af539a 100644 --- a/source4/heimdal/lib/krb5/rd_error.c +++ b/source4/heimdal/lib/krb5/rd_error.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: rd_error.c 21057 2007-06-12 17:22:31Z lha $"); +RCSID("$Id: rd_error.c 23316 2008-06-23 04:32:32Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_error(krb5_context context, @@ -78,7 +78,7 @@ krb5_error_from_rd_error(krb5_context context, ret = error->error_code; if (error->e_text != NULL) { - krb5_set_error_string(context, "%s", *error->e_text); + krb5_set_error_message(context, ret, "%s", *error->e_text); } else { char clientname[256], servername[256]; @@ -91,28 +91,28 @@ krb5_error_from_rd_error(krb5_context context, switch (ret) { case KRB5KDC_ERR_NAME_EXP : - krb5_set_error_string(context, "Client %s%s%s expired", - creds ? "(" : "", - creds ? clientname : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Client %s%s%s expired", + creds ? "(" : "", + creds ? clientname : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_SERVICE_EXP : - krb5_set_error_string(context, "Server %s%s%s expired", - creds ? "(" : "", - creds ? servername : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Server %s%s%s expired", + creds ? "(" : "", + creds ? servername : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN : - krb5_set_error_string(context, "Client %s%s%s unknown", - creds ? "(" : "", - creds ? clientname : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Client %s%s%s unknown", + creds ? "(" : "", + creds ? clientname : "", + creds ? ")" : ""); break; case KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN : - krb5_set_error_string(context, "Server %s%s%s unknown", - creds ? "(" : "", - creds ? servername : "", - creds ? ")" : ""); + krb5_set_error_message(context, ret, "Server %s%s%s unknown", + creds ? "(" : "", + creds ? servername : "", + creds ? ")" : ""); break; default : krb5_clear_error_string(context); diff --git a/source4/heimdal/lib/krb5/rd_rep.c b/source4/heimdal/lib/krb5/rd_rep.c index 8c9b7bb441..0e6e3d09af 100644 --- a/source4/heimdal/lib/krb5/rd_rep.c +++ b/source4/heimdal/lib/krb5/rd_rep.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_rep.c 17890 2006-08-21 09:19:22Z lha $"); +RCSID("$Id: rd_rep.c 23304 2008-06-23 03:29:56Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_rd_rep(krb5_context context, @@ -79,7 +79,7 @@ krb5_rd_rep(krb5_context context, *repl = malloc(sizeof(**repl)); if (*repl == NULL) { ret = ENOMEM; - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } ret = krb5_decode_EncAPRepPart(context, diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 0f33b97164..ddf1f69ae4 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -33,7 +33,7 @@ #include <krb5_locl.h> -RCSID("$Id: rd_req.c 22235 2007-12-08 21:52:07Z lha $"); +RCSID("$Id: rd_req.c 23415 2008-07-26 18:35:44Z lha $"); static krb5_error_code decrypt_tkt_enc_part (krb5_context context, @@ -133,7 +133,7 @@ static krb5_error_code check_transited(krb5_context context, Ticket *ticket, EncTicketPart *enc) { char **realms; - int num_realms; + unsigned int num_realms; krb5_error_code ret; /* @@ -389,11 +389,6 @@ krb5_verify_ap_req2(krb5_context context, t->ticket.crealm); if (ret) goto out; - /* save key */ - - ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock); - if (ret) goto out; - ret = decrypt_authenticator (context, &t->ticket.key, &ap_req->authenticator, @@ -479,6 +474,10 @@ krb5_verify_ap_req2(krb5_context context, } } + /* save key */ + ret = krb5_copy_keyblock(context, &t->ticket.key, &ac->keyblock); + if (ret) goto out; + if (ap_req_options) { *ap_req_options = 0; if (ac->keytype != ETYPE_NULL) @@ -533,7 +532,7 @@ krb5_rd_req_in_ctx_alloc(krb5_context context, krb5_rd_req_in_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } (*ctx)->check_pac = (context->flags & KRB5_CTX_F_CHECK_PAC) ? 1 : 0; @@ -616,7 +615,7 @@ _krb5_rd_req_out_ctx_alloc(krb5_context context, krb5_rd_req_out_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "out of memory"); return ENOMEM; } return 0; @@ -805,9 +804,9 @@ krb5_rd_req_ctx(krb5_context context, } if (ap_req.ap_options.use_session_key && (*auth_context)->keyblock == NULL) { - krb5_set_error_string(context, "krb5_rd_req: user to user auth " - "without session key given"); ret = KRB5KRB_AP_ERR_NOKEY; + krb5_set_error_message(context, ret, "krb5_rd_req: user to user auth " + "without session key given"); goto out; } diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c index 12894d96a9..7639bfa2ce 100644 --- a/source4/heimdal/lib/krb5/replay.c +++ b/source4/heimdal/lib/krb5/replay.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <vis.h> -RCSID("$Id: replay.c 17047 2006-04-10 17:13:49Z lha $"); +RCSID("$Id: replay.c 23467 2008-07-27 12:16:37Z lha $"); struct krb5_rcache_data { char *name; @@ -47,7 +47,7 @@ krb5_rc_resolve(krb5_context context, { id->name = strdup(name); if(id->name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory"); return KRB5_RC_MALLOC; } return 0; @@ -60,13 +60,14 @@ krb5_rc_resolve_type(krb5_context context, { *id = NULL; if(strcmp(type, "FILE")) { - krb5_set_error_string (context, "replay cache type %s not supported", - type); + krb5_set_error_message (context, KRB5_RC_TYPE_NOTFOUND, + "replay cache type %s not supported", + type); return KRB5_RC_TYPE_NOTFOUND; } *id = calloc(1, sizeof(**id)); if(*id == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, KRB5_RC_MALLOC, "malloc: out of memory"); return KRB5_RC_MALLOC; } return 0; @@ -82,7 +83,8 @@ krb5_rc_resolve_full(krb5_context context, *id = NULL; if(strncmp(string_name, "FILE:", 5)) { - krb5_set_error_string (context, "replay cache type %s not supported", + krb5_set_error_message(context, KRB5_RC_TYPE_NOTFOUND, + "replay cache type %s not supported", string_name); return KRB5_RC_TYPE_NOTFOUND; } @@ -132,7 +134,7 @@ krb5_rc_initialize(krb5_context context, if(f == NULL) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, ret, "open(%s): %s", id->name, strerror(ret)); return ret; } @@ -157,7 +159,7 @@ krb5_rc_destroy(krb5_context context, if(remove(id->name) < 0) { ret = errno; - krb5_set_error_string (context, "remove(%s): %s", id->name, + krb5_set_error_message(context, ret, "remove(%s): %s", id->name, strerror(ret)); return ret; } @@ -204,10 +206,11 @@ krb5_rc_store(krb5_context context, f = fopen(id->name, "r"); if(f == NULL) { ret = errno; - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, ret, "open(%s): %s", id->name, strerror(ret)); return ret; } + rk_cloexec_file(f); fread(&tmp, sizeof(ent), 1, f); t = ent.stamp - tmp.stamp; while(fread(&tmp, sizeof(ent), 1, f)){ @@ -222,13 +225,15 @@ krb5_rc_store(krb5_context context, if(ferror(f)){ ret = errno; fclose(f); - krb5_set_error_string (context, "%s: %s", id->name, strerror(ret)); + krb5_set_error_message(context, ret, "%s: %s", + id->name, strerror(ret)); return ret; } fclose(f); f = fopen(id->name, "a"); if(f == NULL) { - krb5_set_error_string (context, "open(%s): %s", id->name, + krb5_set_error_message(context, KRB5_RC_IO_UNKNOWN, + "open(%s): %s", id->name, strerror(errno)); return KRB5_RC_IO_UNKNOWN; } @@ -288,7 +293,7 @@ krb5_get_server_rcache(krb5_context context, char *name; if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL); @@ -299,7 +304,7 @@ krb5_get_server_rcache(krb5_context context, #endif free(tmp); if(name == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index 2582a615c0..1ddb5afd1f 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -32,8 +32,9 @@ */ #include "krb5_locl.h" +#include "send_to_kdc_plugin.h" -RCSID("$Id: send_to_kdc.c 21934 2007-08-27 14:21:04Z lha $"); +RCSID("$Id: send_to_kdc.c 23448 2008-07-27 12:09:22Z lha $"); struct send_to_kdc { krb5_send_to_kdc_func func; @@ -290,6 +291,7 @@ send_via_proxy (krb5_context context, s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (s < 0) continue; + rk_cloexec(s); if (connect (s, a->ai_addr, a->ai_addrlen) < 0) { close (s); continue; @@ -316,6 +318,46 @@ send_via_proxy (krb5_context context, return 1; } +static krb5_error_code +send_via_plugin(krb5_context context, + krb5_krbhst_info *hi, + time_t timeout, + const krb5_data *send_data, + krb5_data *receive) +{ + struct krb5_plugin *list = NULL, *e; + krb5_error_code ret; + + ret = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, KRB5_PLUGIN_SEND_TO_KDC, &list); + if(ret != 0 || list == NULL) + return KRB5_PLUGIN_NO_HANDLE; + + for (e = list; e != NULL; e = _krb5_plugin_get_next(e)) { + krb5plugin_send_to_kdc_ftable *service; + void *ctx; + + service = _krb5_plugin_get_symbol(e); + if (service->minor_version != 0) + continue; + + (*service->init)(context, &ctx); + ret = (*service->send_to_kdc)(context, ctx, hi, + timeout, send_data, receive); + (*service->fini)(ctx); + if (ret == 0) + break; + if (ret != KRB5_PLUGIN_NO_HANDLE) { + krb5_set_error_message(context, ret, + "Plugin %s failed to lookup with error: %d", + KRB5_PLUGIN_SEND_TO_KDC, ret); + break; + } + } + _krb5_plugin_free(list); + return KRB5_PLUGIN_NO_HANDLE; +} + + /* * Send the data `send' to one host from `handle` and get back the reply * in `receive'. @@ -343,12 +385,19 @@ krb5_sendto (krb5_context context, struct send_to_kdc *s = context->send_to_kdc; ret = (*s->func)(context, s->data, - hi, send_data, receive); + hi, context->kdc_timeout, send_data, receive); if (ret == 0 && receive->length != 0) goto out; continue; } + ret = send_via_plugin(context, hi, context->kdc_timeout, + send_data, receive); + if (ret == 0 && receive->length != 0) + goto out; + else if (ret != KRB5_PLUGIN_NO_HANDLE) + continue; + if(hi->proto == KRB5_KRBHST_HTTP && context->http_proxy) { if (send_via_proxy (context, hi, send_data, receive) == 0) { ret = 0; @@ -365,6 +414,7 @@ krb5_sendto (krb5_context context, fd = socket (a->ai_family, a->ai_socktype, a->ai_protocol); if (fd < 0) continue; + rk_cloexec(fd); if (connect (fd, a->ai_addr, a->ai_addrlen) < 0) { close (fd); continue; @@ -439,7 +489,7 @@ krb5_set_send_to_kdc_func(krb5_context context, context->send_to_kdc = malloc(sizeof(*context->send_to_kdc)); if (context->send_to_kdc == NULL) { - krb5_set_error_string(context, "Out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } @@ -460,7 +510,7 @@ krb5_sendto_ctx_alloc(krb5_context context, krb5_sendto_ctx *ctx) { *ctx = calloc(1, sizeof(**ctx)); if (*ctx == NULL) { - krb5_set_error_string(context, "out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } return 0; @@ -566,8 +616,8 @@ krb5_sendto_context(krb5_context context, if (handle) krb5_krbhst_free(context, handle); if (ret == KRB5_KDC_UNREACH) - krb5_set_error_string(context, - "unable to reach any KDC in realm %s", realm); + krb5_set_error_message(context, ret, + "unable to reach any KDC in realm %s", realm); if (ret) krb5_data_free(receive); if (freectx) diff --git a/source4/heimdal/lib/krb5/send_to_kdc_plugin.h b/source4/heimdal/lib/krb5/send_to_kdc_plugin.h new file mode 100644 index 0000000000..e0c2979e28 --- /dev/null +++ b/source4/heimdal/lib/krb5/send_to_kdc_plugin.h @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2008 Kungliga Tekniska Högskolan + * (Royal Institute of Technology, Stockholm, Sweden). + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the Institute nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* $Id$ */ + +#ifndef HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H +#define HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H 1 + +#include <krb5.h> + +#define KRB5_PLUGIN_SEND_TO_KDC "send_to_kdc" + +typedef krb5_error_code +(*krb5plugin_send_to_kdc_func)(krb5_context, + void *, + krb5_krbhst_info *, + time_t timeout, + const krb5_data *, + krb5_data *); + +typedef struct krb5plugin_send_to_kdc_ftable { + int minor_version; + krb5_error_code (*init)(krb5_context, void **); + void (*fini)(void *); + krb5plugin_send_to_kdc_func send_to_kdc; +} krb5plugin_send_to_kdc_ftable; + +#endif /* HEIMDAL_KRB5_SEND_TO_KDC_PLUGIN_H */ diff --git a/source4/heimdal/lib/krb5/set_default_realm.c b/source4/heimdal/lib/krb5/set_default_realm.c index 98040bc2e9..55abf2ea7d 100644 --- a/source4/heimdal/lib/krb5/set_default_realm.c +++ b/source4/heimdal/lib/krb5/set_default_realm.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: set_default_realm.c 13863 2004-05-25 21:46:46Z lha $"); +RCSID("$Id: set_default_realm.c 23309 2008-06-23 03:30:41Z lha $"); /* * Convert the simple string `s' into a NULL-terminated and freshly allocated @@ -46,13 +46,13 @@ string_to_list (krb5_context context, const char *s, krb5_realm **list) *list = malloc (2 * sizeof(**list)); if (*list == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*list)[0] = strdup (s); if ((*list)[0] == NULL) { free (*list); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } (*list)[1] = NULL; diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 7eb4d32fad..5eff64e12d 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -RCSID("$Id: ticket.c 19544 2006-12-28 20:49:18Z lha $"); +RCSID("$Id: ticket.c 23310 2008-06-23 03:30:49Z lha $"); krb5_error_code KRB5_LIB_FUNCTION krb5_free_ticket(krb5_context context, @@ -57,7 +57,7 @@ krb5_copy_ticket(krb5_context context, *to = NULL; tmp = malloc(sizeof(*tmp)); if(tmp == NULL) { - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } if((ret = copy_EncTicketPart(&from->ticket, &tmp->ticket))){ @@ -118,9 +118,10 @@ find_type_in_ad(krb5_context context, int i; if (level > 9) { - krb5_set_error_string(context, "Authorization data nested deeper " - "then %d levels, stop searching", level); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, + "Authorization data nested deeper " + "then %d levels, stop searching", level); goto out; } @@ -133,7 +134,7 @@ find_type_in_ad(krb5_context context, if (!*found && ad->val[i].ad_type == type) { ret = der_copy_octet_string(&ad->val[i].ad_data, data); if (ret) { - krb5_set_error_string(context, "malloc - out of memory"); + krb5_set_error_message(context, ret, "malloc: out of memory"); goto out; } *found = TRUE; @@ -147,8 +148,8 @@ find_type_in_ad(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "IF_RELEVANT with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "IF_RELEVANT with %d", (int)ret); goto out; } ret = find_type_in_ad(context, type, data, found, FALSE, @@ -167,8 +168,8 @@ find_type_in_ad(krb5_context context, &child, NULL); if (ret) { - krb5_set_error_string(context, "Failed to decode " - "AD_KDCIssued with %d", ret); + krb5_set_error_message(context, ret, "Failed to decode " + "AD_KDCIssued with %d", ret); goto out; } if (failp) { @@ -211,17 +212,17 @@ find_type_in_ad(krb5_context context, case KRB5_AUTHDATA_AND_OR: if (!failp) break; - krb5_set_error_string(context, "Authorization data contains " - "AND-OR element that is unknown to the " - "application"); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, "Authorization data contains " + "AND-OR element that is unknown to the " + "application"); goto out; default: if (!failp) break; - krb5_set_error_string(context, "Authorization data contains " - "unknown type (%d) ", ad->val[i].ad_type); ret = ENOENT; /* XXX */ + krb5_set_error_message(context, ret, "Authorization data contains " + "unknown type (%d) ", ad->val[i].ad_type); goto out; } } @@ -255,7 +256,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context, ad = ticket->ticket.authorization_data; if (ticket->ticket.authorization_data == NULL) { - krb5_set_error_string(context, "Ticket have not authorization data"); + krb5_set_error_message(context, ENOENT, + "Ticket have not authorization data"); return ENOENT; /* XXX */ } @@ -264,8 +266,8 @@ krb5_ticket_get_authorization_data_type(krb5_context context, if (ret) return ret; if (!found) { - krb5_set_error_string(context, "Ticket have not authorization " - "data of type %d", type); + krb5_set_error_message(context, ENOENT, "Ticket have not " + "authorization data of type %d", type); return ENOENT; /* XXX */ } return 0; diff --git a/source4/heimdal/lib/krb5/time.c b/source4/heimdal/lib/krb5/time.c index 4cd992d48f..46f88a86cd 100644 --- a/source4/heimdal/lib/krb5/time.c +++ b/source4/heimdal/lib/krb5/time.c @@ -33,12 +33,20 @@ #include "krb5_locl.h" -RCSID("$Id: time.c 14308 2004-10-13 17:57:11Z lha $"); +RCSID("$Id: time.c 23260 2008-06-21 15:22:37Z lha $"); -/* +/** * Set the absolute time that the caller knows the kdc has so the * kerberos library can calculate the relative diffrence beteen the * KDC time and local system time. + * + * @param context Keberos 5 context. + * @param sec The applications new of "now" in seconds + * @param usec The applications new of "now" in micro seconds + + * @return Kerberos 5 error code, see krb5_get_error_message(). + * + * @ingroup krb5 */ krb5_error_code KRB5_LIB_FUNCTION @@ -51,12 +59,21 @@ krb5_set_real_time (krb5_context context, gettimeofday(&tv, NULL); context->kdc_sec_offset = sec - tv.tv_sec; - context->kdc_usec_offset = usec - tv.tv_usec; - if (context->kdc_usec_offset < 0) { - context->kdc_sec_offset--; - context->kdc_usec_offset += 1000000; - } + /** + * If the caller passes in a negative usec, its assumed to be + * unknown and the function will use the current time usec. + */ + if (usec >= 0) { + context->kdc_usec_offset = usec - tv.tv_usec; + + if (context->kdc_usec_offset < 0) { + context->kdc_sec_offset--; + context->kdc_usec_offset += 1000000; + } + } else + context->kdc_usec_offset = tv.tv_usec; + return 0; } diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c index 9b67ecc04f..58b00a4b7a 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 21745 2007-07-31 16:11:25Z lha $"); +RCSID("$Id: transited.c 23316 2008-06-23 04:32:32Z lha $"); /* this is an attempt at one of the most horrible `compression' schemes that has ever been invented; it's so amazingly brain-dead @@ -88,7 +88,7 @@ make_path(krb5_context context, struct tr_realm *r, break; tmp = calloc(1, sizeof(*tmp)); if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } tmp->next = path; @@ -96,7 +96,7 @@ make_path(krb5_context context, struct tr_realm *r, path->realm = strdup(p); if(path->realm == NULL){ r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM;; } } @@ -112,7 +112,7 @@ make_path(krb5_context context, struct tr_realm *r, break; tmp = calloc(1, sizeof(*tmp)); if(tmp == NULL){ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } tmp->next = path; @@ -120,7 +120,7 @@ make_path(krb5_context context, struct tr_realm *r, path->realm = malloc(p - from + 1); if(path->realm == NULL){ r->next = path; /* XXX */ - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(path->realm, from, p - from); @@ -186,7 +186,7 @@ expand_realms(krb5_context context, tmp = realloc(r->realm, len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } r->realm = tmp; @@ -200,7 +200,7 @@ expand_realms(krb5_context context, tmp = malloc(len); if(tmp == NULL){ free_realms(realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } strlcpy(tmp, prev_realm, len); @@ -286,7 +286,7 @@ 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"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); @@ -294,7 +294,7 @@ decode_realms(krb5_context context, r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); @@ -304,7 +304,7 @@ 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"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } memcpy(tmp, start, tr + i - start); @@ -312,7 +312,7 @@ decode_realms(krb5_context context, r = make_realm(tmp); if(r == NULL){ free_realms(*realms); - krb5_set_error_string (context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } *realms = append_realm(*realms, r); @@ -323,7 +323,7 @@ decode_realms(krb5_context context, krb5_error_code KRB5_LIB_FUNCTION krb5_domain_x500_decode(krb5_context context, - krb5_data tr, char ***realms, int *num_realms, + krb5_data tr, char ***realms, unsigned int *num_realms, const char *client_realm, const char *server_realm) { struct tr_realm *r = NULL; @@ -385,11 +385,12 @@ krb5_domain_x500_decode(krb5_context context, } krb5_error_code KRB5_LIB_FUNCTION -krb5_domain_x500_encode(char **realms, int num_realms, krb5_data *encoding) +krb5_domain_x500_encode(char **realms, unsigned int num_realms, + krb5_data *encoding) { char *s = NULL; int len = 0; - int i; + unsigned int i; krb5_data_zero(encoding); if (num_realms == 0) return 0; @@ -420,7 +421,7 @@ krb5_check_transited(krb5_context context, krb5_const_realm client_realm, krb5_const_realm server_realm, krb5_realm *realms, - int num_realms, + unsigned int num_realms, int *bad_realm) { char **tr_realms; @@ -442,8 +443,9 @@ krb5_check_transited(krb5_context context, } if(p == NULL || *p == NULL) { krb5_config_free_strings(tr_realms); - krb5_set_error_string (context, "no transit through realm %s", - realms[i]); + krb5_set_error_message (context, KRB5KRB_AP_ERR_ILL_CR_TKT, + "no transit through realm %s", + realms[i]); if(bad_realm) *bad_realm = i; return KRB5KRB_AP_ERR_ILL_CR_TKT; @@ -456,7 +458,7 @@ krb5_check_transited(krb5_context context, krb5_error_code KRB5_LIB_FUNCTION krb5_check_transited_realms(krb5_context context, const char *const *realms, - int num_realms, + unsigned int num_realms, int *bad_realm) { int i; @@ -472,9 +474,9 @@ krb5_check_transited_realms(krb5_context context, char **p; for(p = bad_realms; *p; p++) if(strcmp(*p, realms[i]) == 0) { - krb5_set_error_string (context, "no transit through realm %s", - *p); ret = KRB5KRB_AP_ERR_ILL_CR_TKT; + krb5_set_error_message (context, ret, + "no transit through realm %s", *p); if(bad_realm) *bad_realm = i; break; diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c index 37b1e35dd1..55570c44dd 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 22071 2007-11-14 20:04:50Z lha $"); +RCSID("$Id: v4_glue.c 23452 2008-07-27 12:10:54Z lha $"); #include "krb5-v4compat.h" @@ -147,7 +147,7 @@ write_v4_cc(krb5_context context, const char *tkfile, ret = get_krb4_cc_name(tkfile, &path); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: failed getting " "the krb4 credentials cache name"); return ret; @@ -156,15 +156,16 @@ write_v4_cc(krb5_context context, const char *tkfile, fd = open(path, O_WRONLY|O_CREAT, 0600); if (fd < 0) { ret = errno; - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: error opening file %s", path); free(path); return ret; } + rk_cloexec(fd); if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: tktfile %s is not a file", path); free(path); @@ -179,9 +180,9 @@ write_v4_cc(krb5_context context, const char *tkfile, break; } if (i == KRB5_TF_LCK_RETRY_COUNT) { - krb5_set_error_string(context, - "krb5_krb_tf_setup: failed to lock %s", - path); + krb5_set_error_message(context, KRB5_FCC_PERM, + "krb5_krb_tf_setup: failed to lock %s", + path); free(path); close(fd); return KRB5_FCC_PERM; @@ -191,9 +192,9 @@ write_v4_cc(krb5_context context, const char *tkfile, ret = ftruncate(fd, 0); if (ret < 0) { flock(fd, LOCK_UN); - krb5_set_error_string(context, - "krb5_krb_tf_setup: failed to truncate %s", - path); + krb5_set_error_message(context, KRB5_FCC_PERM, + "krb5_krb_tf_setup: failed to truncate %s", + path); free(path); close(fd); return KRB5_FCC_PERM; @@ -291,7 +292,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile) ret = get_krb4_cc_name(tkfile, &path); if (ret) { - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_tf_setup: failed getting " "the krb4 credentials cache name"); return ret; @@ -299,7 +300,7 @@ _krb5_krb_dest_tkt(krb5_context context, const char *tkfile) if (unlink(path) < 0) { ret = errno; - krb5_set_error_string(context, + krb5_set_error_message(context, ret, "krb5_krb_dest_tkt failed removing the cache " "with error %s", strerror(ret)); } @@ -421,7 +422,7 @@ _krb5_krb_create_ticket(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -448,7 +449,7 @@ _krb5_krb_create_ticket(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -477,7 +478,7 @@ _krb5_krb_create_ciph(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -507,7 +508,7 @@ _krb5_krb_create_ciph(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -535,7 +536,7 @@ _krb5_krb_create_auth_reply(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -559,7 +560,7 @@ _krb5_krb_create_auth_reply(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 ticket"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 ticket"); return ret; } @@ -590,7 +591,7 @@ _krb5_krb_cr_err_reply(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) { - krb5_set_error_string(context, "malloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); @@ -610,7 +611,7 @@ _krb5_krb_cr_err_reply(krb5_context context, error: krb5_storage_free(sp); if (ret) - krb5_set_error_string(context, "Failed to encode kerberos 4 error"); + krb5_set_error_message(context, ret, "Failed to encode kerberos 4 error"); return 0; } @@ -661,7 +662,7 @@ _krb5_krb_decomp_ticket(krb5_context context, sp = krb5_storage_from_data(&ticket); if (sp == NULL) { krb5_data_free(&ticket); - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "alloc: out of memory"); return ENOMEM; } @@ -720,7 +721,7 @@ _krb5_krb_decomp_ticket(krb5_context context, *sinstance = NULL; } _krb5_krb_free_auth_data(context, ad); - krb5_set_error_string(context, "Failed to decode v4 ticket"); + krb5_set_error_message(context, ret, "Failed to decode v4 ticket"); } return ret; } @@ -769,7 +770,7 @@ _krb5_krb_rd_req(krb5_context context, sp = krb5_storage_from_data(authent); if (sp == NULL) { - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ENOMEM, "alloc: out of memory"); return ENOMEM; } @@ -777,19 +778,19 @@ _krb5_krb_rd_req(krb5_context context, ret = krb5_ret_int8(sp, &pvno); if (ret) { - krb5_set_error_string(context, "Failed reading v4 pvno"); + krb5_set_error_message(context, ret, "Failed reading v4 pvno"); goto error; } if (pvno != KRB_PROT_VERSION) { ret = KRB4ET_RD_AP_VERSION; - krb5_set_error_string(context, "Failed v4 pvno not 4"); + krb5_set_error_message(context, ret, "Failed v4 pvno not 4"); goto error; } ret = krb5_ret_int8(sp, &type); if (ret) { - krb5_set_error_string(context, "Failed readin v4 type"); + krb5_set_error_message(context, ret, "Failed readin v4 type"); goto error; } @@ -798,7 +799,7 @@ _krb5_krb_rd_req(krb5_context context, if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) { ret = KRB4ET_RD_AP_MSG_TYPE; - krb5_set_error_string(context, "Not a valid v4 request type"); + krb5_set_error_message(context, ret, "Not a valid v4 request type"); goto error; } @@ -811,7 +812,7 @@ _krb5_krb_rd_req(krb5_context context, size = krb5_storage_read(sp, ticket.data, ticket.length); if (size != ticket.length) { ret = KRB4ET_INTK_PROT; - krb5_set_error_string(context, "Failed reading v4 ticket"); + krb5_set_error_message(context, ret, "Failed reading v4 ticket"); goto error; } @@ -826,7 +827,7 @@ _krb5_krb_rd_req(krb5_context context, size = krb5_storage_read(sp, eaut.data, eaut.length); if (size != eaut.length) { ret = KRB4ET_INTK_PROT; - krb5_set_error_string(context, "Failed reading v4 authenticator"); + krb5_set_error_message(context, ret, "Failed reading v4 authenticator"); goto error; } @@ -840,7 +841,7 @@ _krb5_krb_rd_req(krb5_context context, sp = krb5_storage_from_data(&aut); if (sp == NULL) { ret = ENOMEM; - krb5_set_error_string(context, "alloc: out of memory"); + krb5_set_error_message(context, ret, "alloc: out of memory"); goto error; } @@ -860,14 +861,14 @@ _krb5_krb_rd_req(krb5_context context, if (strcmp(ad->pname, r_name) != 0 || strcmp(ad->pinst, r_instance) != 0 || strcmp(ad->prealm, r_realm) != 0) { - krb5_set_error_string(context, "v4 principal mismatch"); ret = KRB4ET_RD_AP_INCON; + krb5_set_error_message(context, ret, "v4 principal mismatch"); goto error; } if (from_addr && ad->address && from_addr != ad->address) { - krb5_set_error_string(context, "v4 bad address in ticket"); ret = KRB4ET_RD_AP_BADD; + krb5_set_error_message(context, ret, "v4 bad address in ticket"); goto error; } @@ -875,7 +876,7 @@ _krb5_krb_rd_req(krb5_context context, delta_t = abs((int)(tv.tv_sec - r_time_sec)); if (delta_t > CLOCK_SKEW) { ret = KRB4ET_RD_AP_TIME; - krb5_set_error_string(context, "v4 clock skew"); + krb5_set_error_message(context, ret, "v4 clock skew"); goto error; } @@ -885,13 +886,13 @@ _krb5_krb_rd_req(krb5_context context, if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) { ret = KRB4ET_RD_AP_NYV; - krb5_set_error_string(context, "v4 clock skew for expiration"); + krb5_set_error_message(context, ret, "v4 clock skew for expiration"); goto error; } if (tv.tv_sec > _krb5_krb_life_to_time(ad->time_sec, ad->life)) { ret = KRB4ET_RD_AP_EXP; - krb5_set_error_string(context, "v4 ticket expired"); + krb5_set_error_message(context, ret, "v4 ticket expired"); goto error; } diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index 85f143b8b4..97a6cc9e0a 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -34,7 +34,7 @@ #include "krb5_locl.h" #include <err.h> -RCSID("$Id: warn.c 19086 2006-11-21 08:06:40Z lha $"); +RCSID("$Id: warn.c 23206 2008-05-29 02:13:41Z lha $"); static krb5_error_code _warnerr(krb5_context context, int do_errtext, krb5_error_code code, int level, const char *fmt, va_list ap) @@ -47,7 +47,7 @@ _warnerr(krb5_context context, int do_errtext, char xfmt[7] = ""; const char *args[2], **arg; char *msg = NULL; - char *err_str = NULL; + const char *err_str = NULL; args[0] = args[1] = NULL; arg = args; @@ -65,7 +65,7 @@ _warnerr(krb5_context context, int do_errtext, strlcat(xfmt, "%s", sizeof(xfmt)); - err_str = krb5_get_error_string(context); + err_str = krb5_get_error_message(context, code); if (err_str != NULL) { *arg++ = err_str; } else { @@ -82,7 +82,7 @@ _warnerr(krb5_context context, int do_errtext, else warnx(xfmt, args[0], args[1]); free(msg); - free(err_str); + krb5_free_error_message(context, err_str); return 0; } |