diff options
author | Matthieu Patou <mat@matws.net> | 2010-08-15 18:31:28 +0400 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2010-10-03 01:15:04 +0000 |
commit | ab6e3fce040f9ad27cbce44e9038a24f15b601c8 (patch) | |
tree | ab99a431c9610927b5d0d26335d2712b509fd6dc /source4/heimdal/lib/krb5 | |
parent | 197a1514d62494cc8b862d169c841a26e04b8925 (diff) | |
download | samba-ab6e3fce040f9ad27cbce44e9038a24f15b601c8.tar.gz samba-ab6e3fce040f9ad27cbce44e9038a24f15b601c8.tar.bz2 samba-ab6e3fce040f9ad27cbce44e9038a24f15b601c8.zip |
s4:heimdal: import lorikeet-heimdal-201009250123 (commit 42cabfb5b683dbcb97d583c397b897507689e382)
I based this on Matthieu's import of lorikeet-heimdal, and then
updated it to this commit.
Andrew Bartlett
Diffstat (limited to 'source4/heimdal/lib/krb5')
36 files changed, 1057 insertions, 504 deletions
diff --git a/source4/heimdal/lib/krb5/acache.c b/source4/heimdal/lib/krb5/acache.c index 19a5997453..6f20cdcf6c 100644 --- a/source4/heimdal/lib/krb5/acache.c +++ b/source4/heimdal/lib/krb5/acache.c @@ -43,8 +43,8 @@ static HEIMDAL_MUTEX acc_mutex = HEIMDAL_MUTEX_INITIALIZER; static cc_initialize_func init_func; -static void (*set_target_uid)(uid_t); -static void (*clear_target)(void); +static void (KRB5_CALLCONV *set_target_uid)(uid_t); +static void (KRB5_CALLCONV *clear_target)(void); #ifdef HAVE_DLOPEN static void *cc_handle; @@ -56,7 +56,7 @@ typedef struct krb5_acc { cc_ccache_t ccache; } krb5_acc; -static krb5_error_code acc_close(krb5_context, krb5_ccache); +static krb5_error_code KRB5_CALLCONV acc_close(krb5_context, krb5_ccache); #define ACACHE(X) ((krb5_acc *)(X)->data.data) @@ -106,6 +106,8 @@ init_ccapi(krb5_context context) if (lib == NULL) { #ifdef __APPLE__ lib = "/System/Library/Frameworks/Kerberos.framework/Kerberos"; +#elif defined(KRB5_USE_PATH_TOKENS) && defined(_WIN32) + lib = "%{LIBDIR}/libkrb5_cc.dll"; #else lib = "/usr/lib/libkrb5_cc.so"; #endif @@ -120,7 +122,18 @@ init_ccapi(krb5_context context) #define RTLD_LOCAL 0 #endif +#ifdef KRB5_USE_PATH_TOKENS + { + char * explib = NULL; + if (_krb5_expand_path_tokens(context, lib, &explib) == 0) { + cc_handle = dlopen(explib, RTLD_LAZY|RTLD_LOCAL); + free(explib); + } + } +#else cc_handle = dlopen(lib, RTLD_LAZY|RTLD_LOCAL); +#endif + if (cc_handle == NULL) { HEIMDAL_MUTEX_unlock(&acc_mutex); if (context) @@ -131,8 +144,10 @@ init_ccapi(krb5_context context) } init_func = (cc_initialize_func)dlsym(cc_handle, "cc_initialize"); - set_target_uid = dlsym(cc_handle, "krb5_ipc_client_set_target_uid"); - clear_target = dlsym(cc_handle, "krb5_ipc_client_clear_target"); + set_target_uid = (void (KRB5_CALLCONV *)(uid_t)) + dlsym(cc_handle, "krb5_ipc_client_set_target_uid"); + clear_target = (void (KRB5_CALLCONV *)(void)) + dlsym(cc_handle, "krb5_ipc_client_clear_target"); HEIMDAL_MUTEX_unlock(&acc_mutex); if (init_func == NULL) { if (context) @@ -157,14 +172,16 @@ void _heim_krb5_ipc_client_set_target_uid(uid_t uid) { init_ccapi(NULL); - (*set_target_uid)(uid); + if (set_target_uid != NULL) + (*set_target_uid)(uid); } void _heim_krb5_ipc_client_clear_target(void) { init_ccapi(NULL); - (*clear_target)(); + if (clear_target != NULL) + (*clear_target)(); } static krb5_error_code @@ -436,7 +453,7 @@ get_cc_name(krb5_acc *a) } -static const char* +static const char* KRB5_CALLCONV acc_get_name(krb5_context context, krb5_ccache id) { @@ -473,7 +490,7 @@ acc_get_name(krb5_context context, return a->cache_name; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_alloc(krb5_context context, krb5_ccache *id) { krb5_error_code ret; @@ -503,7 +520,7 @@ acc_alloc(krb5_context context, krb5_ccache *id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_resolve(krb5_context context, krb5_ccache *id, const char *res) { krb5_error_code ret; @@ -543,7 +560,7 @@ acc_resolve(krb5_context context, krb5_ccache *id, const char *res) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_gen_new(krb5_context context, krb5_ccache *id) { krb5_error_code ret; @@ -561,7 +578,7 @@ acc_gen_new(krb5_context context, krb5_ccache *id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) @@ -615,7 +632,7 @@ acc_initialize(krb5_context context, return translate_cc_error(context, error); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_close(krb5_context context, krb5_ccache id) { @@ -637,7 +654,7 @@ acc_close(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_destroy(krb5_context context, krb5_ccache id) { @@ -655,7 +672,7 @@ acc_destroy(krb5_context context, return translate_cc_error(context, error); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) @@ -690,7 +707,7 @@ acc_store_cred(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) @@ -718,7 +735,7 @@ acc_get_principal(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_first (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -743,7 +760,7 @@ acc_get_first (krb5_context context, } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, @@ -770,7 +787,7 @@ acc_get_next (krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_end_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -780,7 +797,7 @@ acc_end_get (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags which, @@ -856,7 +873,7 @@ acc_remove_cred(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) @@ -864,7 +881,7 @@ acc_set_flags(krb5_context context, return 0; } -static int +static int KRB5_CALLCONV acc_get_version(krb5_context context, krb5_ccache id) { @@ -876,7 +893,7 @@ struct cache_iter { cc_ccache_iterator_t iter; }; -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) { struct cache_iter *iter; @@ -910,7 +927,7 @@ acc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) { struct cache_iter *iter = cursor; @@ -948,7 +965,7 @@ acc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) { struct cache_iter *iter = cursor; @@ -961,7 +978,7 @@ acc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_acc *afrom = ACACHE(from); @@ -993,7 +1010,7 @@ acc_move(krb5_context context, krb5_ccache from, krb5_ccache to) return translate_cc_error(context, error); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_get_default_name(krb5_context context, char **str) { krb5_error_code ret; @@ -1015,18 +1032,18 @@ acc_get_default_name(krb5_context context, char **str) return translate_cc_error(context, error); } - asprintf(str, "API:%s", name->data); + error = asprintf(str, "API:%s", name->data); (*name->func->release)(name); (*cc->func->release)(cc); - if (*str == NULL) { + if (error < 0 || *str == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_set_default(krb5_context context, krb5_ccache id) { krb5_acc *a = ACACHE(id); @@ -1045,7 +1062,7 @@ acc_set_default(krb5_context context, krb5_ccache id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV acc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) { krb5_acc *a = ACACHE(id); diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index ce8040d07c..32a131b07c 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -83,7 +83,7 @@ main (int argc, char **argv) while((ret = krb5_cc_next_cred(context, id, &cursor, &creds)) == 0){ char *principal; - krb5_unparse_name_short(context, creds.server, &principal); + krb5_unparse_name(context, creds.server, &principal); printf("principal: %s\\n", principal); free(principal); krb5_free_cred_contents (context, &creds); @@ -206,8 +206,10 @@ allocate_ccache (krb5_context context, } ret = (*id)->ops->resolve(context, id, residual); - if(ret) + if(ret) { free(*id); + *id = NULL; + } #ifdef KRB5_USE_PATH_TOKENS if (exp_residual) @@ -217,6 +219,25 @@ allocate_ccache (krb5_context context, return ret; } +static int +is_possible_path_name(const char * name) +{ + const char * colon; + + if ((colon = strchr(name, ':')) == NULL) + return TRUE; + +#ifdef _WIN32 + /* <drive letter>:\path\to\cache ? */ + + if (colon == name + 1 && + strchr(colon + 1, ':') == NULL) + return TRUE; +#endif + + return FALSE; +} + /** * Find and allocate a ccache in `id' from the specification in `residual'. * If the ccache name doesn't contain any colon, interpret it as a file name. @@ -251,7 +272,7 @@ krb5_cc_resolve(krb5_context context, id); } } - if (strchr (name, ':') == NULL) + if (is_possible_path_name(name)) return allocate_ccache (context, &krb5_fcc_ops, name, id); else { krb5_set_error_message(context, KRB5_CC_UNKNOWN_TYPE, @@ -389,84 +410,7 @@ krb5_cc_get_ops(krb5_context context, krb5_ccache id) krb5_error_code _krb5_expand_default_cc_name(krb5_context context, const char *str, char **res) { -#ifndef KRB5_USE_PATH_TOKENS - size_t tlen, len = 0; - char *tmp, *tmp2, *append; - - *res = NULL; - - while (str && *str) { - tmp = strstr(str, "%{"); - if (tmp && tmp != str) { - append = malloc((tmp - str) + 1); - if (append) { - memcpy(append, str, tmp - str); - append[tmp - str] = '\0'; - } - str = tmp; - } else if (tmp) { - tmp2 = strchr(tmp, '}'); - if (tmp2 == NULL) { - if (*res) - free(*res); - *res = NULL; - krb5_set_error_message(context, KRB5_CONFIG_BADFORMAT, - "variable missing }"); - return KRB5_CONFIG_BADFORMAT; - } - if (strncasecmp(tmp, "%{uid}", 6) == 0) - asprintf(&append, "%u", (unsigned)getuid()); - else if (strncasecmp(tmp, "%{null}", 7) == 0) - append = strdup(""); - else { - if (*res) - free(*res); - *res = NULL; - 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; - } else { - append = strdup(str); - str = NULL; - } - if (append == NULL) { - if (*res) - free(*res); - *res = NULL; - krb5_set_error_message(context, ENOMEM, - N_("malloc: out of memory", "")); - return ENOMEM; - } - - tlen = strlen(append); - tmp = realloc(*res, len + tlen + 1); - if (tmp == NULL) { - free(append); - if (*res) - free(*res); - *res = NULL; - krb5_set_error_message(context, ENOMEM, - N_("malloc: out of memory", "")); - return ENOMEM; - } - *res = tmp; - memcpy(*res + len, append, tlen + 1); - len = len + tlen; - free(append); - } - return 0; -#else /* _WIN32 */ - /* On Windows, we use the more generic _krb5_expand_path_tokens() - function which also handles path tokens in addition to %{uid} - and %{null} */ - return _krb5_expand_path_tokens(context, str, res); -#endif } /* @@ -554,7 +498,7 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_cc_set_default_name(krb5_context context, const char *name) { krb5_error_code ret = 0; - char *p; + char *p = NULL, *exp_p = NULL; if (name == NULL) { const char *e = NULL; @@ -606,26 +550,17 @@ krb5_cc_set_default_name(krb5_context context, const char *name) return ENOMEM; } -#ifdef KRB5_USE_PATH_TOKENS - { - char * exp_p = NULL; - - if (_krb5_expand_path_tokens(context, p, &exp_p) == 0) { - free (p); - p = exp_p; - } else { - free (p); - return EINVAL; - } - } -#endif + ret = _krb5_expand_path_tokens(context, p, &exp_p); + free(p); + if (ret) + return ret; if (context->default_cc_name) free(context->default_cc_name); - context->default_cc_name = p; + context->default_cc_name = exp_p; - return ret; + return 0; } /** @@ -1499,7 +1434,7 @@ krb5_cccol_cursor_next(krb5_context context, krb5_cccol_cursor cursor, cursor->cursor = NULL; if (ret != KRB5_CC_END) break; - + cursor->idx++; } if (cursor->idx >= context->num_cc_ops) { diff --git a/source4/heimdal/lib/krb5/ccache_plugin.h b/source4/heimdal/lib/krb5/ccache_plugin.h new file mode 100644 index 0000000000..f6871d65d1 --- /dev/null +++ b/source4/heimdal/lib/krb5/ccache_plugin.h @@ -0,0 +1,39 @@ +/*********************************************************************** + * Copyright (c) 2010, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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. + * + **********************************************************************/ + +#ifndef HEIMDAL_KRB5_CCACHE_PLUGIN_H +#define HEIMDAL_KRB5_CCACHE_PLUGIN_H 1 + +#include <krb5.h> + +#define KRB5_PLUGIN_CCACHE "ccache_ops" + +#endif /* HEIMDAL_KRB5_CCACHE_PLUGIN_H */ diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index 4eb4e12fad..22d0b90bd8 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -239,7 +239,12 @@ parse_binding(struct fileptr *f, unsigned *lineno, char *p, return ret; } -#ifdef __APPLE__ +#if defined(__APPLE__) + +#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 +#define HAVE_CFPROPERTYLISTCREATEWITHSTREAM 1 +#endif + static char * cfstring2cstring(CFStringRef string) { @@ -293,7 +298,6 @@ parse_plist_config(krb5_context context, const char *path, krb5_config_section * { CFReadStreamRef s; CFDictionaryRef d; - CFErrorRef e; CFURLRef url; url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (UInt8 *)path, strlen(path), FALSE); @@ -315,7 +319,11 @@ parse_plist_config(krb5_context context, const char *path, krb5_config_section * return ENOENT; } - d = (CFDictionaryRef)CFPropertyListCreateWithStream (kCFAllocatorDefault, s, 0, kCFPropertyListImmutable, NULL, &e); +#ifdef HAVE_CFPROPERTYLISTCREATEWITHSTREAM + d = (CFDictionaryRef)CFPropertyListCreateWithStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL); +#else + d = (CFDictionaryRef)CFPropertyListCreateFromStream(NULL, s, 0, kCFPropertyListImmutable, NULL, NULL); +#endif CFRelease(s); if (d == NULL) { krb5_clear_error_message(context); @@ -447,8 +455,9 @@ krb5_config_parse_file_multi (krb5_context context, fname = newfname; } #else /* KRB5_USE_PATH_TOKENS */ - asprintf(&newfname, "%%{USERCONFIG}/%s", &fname[1]); - if (newfname == NULL) { + if (asprintf(&newfname, "%%{USERCONFIG}%s", &fname[1]) < 0 || + newfname == NULL) + { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index adcbb703ee..0897c5e7a0 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997 - 2005 Kungliga Tekniska Högskolan + * Copyright (c) 1997 - 2010 Kungliga Tekniska Högskolan * (Royal Institute of Technology, Stockholm, Sweden). * All rights reserved. * @@ -215,6 +215,14 @@ init_context_from_config_file(krb5_context context) krb5_config_free_strings(s); } + tmp = krb5_config_get_string(context, NULL, "libdefaults", + "check-rd-req-server", NULL); + if (tmp == NULL && !issuid()) + tmp = getenv("KRB5_CHECK_RD_REQ_SERVER"); + if(tmp) { + if (strcasecmp(tmp, "ignore") == 0) + context->flags |= KRB5_CTX_F_RD_REQ_IGNORE; + } return 0; } @@ -239,6 +247,7 @@ cc_ops_register(krb5_context context) #endif krb5_cc_register(context, &krb5_kcm_ops, TRUE); #endif + _krb5_load_ccache_plugins(context); return 0; } @@ -380,6 +389,13 @@ out: #ifndef HEIMDAL_SMALLER +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_get_permitted_enctypes(krb5_context context, + krb5_enctype **etypes) +{ + return krb5_get_default_in_tkt_etypes(context, etypes); +} + /* * */ diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index eda5e634d1..47f910260e 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -96,11 +96,11 @@ struct checksum_type { size_t blocksize; size_t checksumsize; unsigned flags; - krb5_enctype (*checksum)(krb5_context context, - struct key_data *key, - const void *buf, size_t len, - unsigned usage, - Checksum *csum); + krb5_error_code (*checksum)(krb5_context context, + struct key_data *key, + const void *buf, size_t len, + unsigned usage, + Checksum *csum); krb5_error_code (*verify)(krb5_context context, struct key_data *key, const void *buf, size_t len, @@ -4004,7 +4004,7 @@ krb5_generate_random_block(void *buf, size_t len) rng_initialized = 1; } HEIMDAL_MUTEX_unlock(&crypto_mutex); - if (RAND_bytes(buf, len) != 1) + if (RAND_bytes(buf, len) <= 0) krb5_abortx(NULL, "Failed to generate random block"); } diff --git a/source4/heimdal/lib/krb5/data.c b/source4/heimdal/lib/krb5/data.c index 838135ffad..c4c202be5d 100644 --- a/source4/heimdal/lib/krb5/data.c +++ b/source4/heimdal/lib/krb5/data.c @@ -87,7 +87,7 @@ krb5_free_data(krb5_context context, /** * Allocate data of and krb5_data. * - * @param p krb5_data to free. + * @param p krb5_data to allocate. * @param len size to allocate. * * @return Returns 0 to indicate success. Otherwise an kerberos et diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index adab6f5e84..237d346f4d 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -96,11 +96,17 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret, const char *fmt, va_list args) __attribute__ ((format (printf, 3, 0))) { + int r; - krb5_clear_error_message(context); HEIMDAL_MUTEX_lock(context->mutex); + if (context->error_string) { + free(context->error_string); + context->error_string = NULL; + } context->error_code = ret; - vasprintf(&context->error_string, fmt, args); + r = vasprintf(&context->error_string, fmt, args); + if (r < 0) + context->error_string = NULL; HEIMDAL_MUTEX_unlock(context->mutex); } @@ -144,19 +150,22 @@ krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, const char *fmt, va_list args) __attribute__ ((format (printf, 3, 0))) { - char *str, *str2; + char *str = NULL, *str2 = NULL; HEIMDAL_MUTEX_lock(context->mutex); if (context->error_code != ret) { HEIMDAL_MUTEX_unlock(context->mutex); return; } - vasprintf(&str, fmt, args); + if (vasprintf(&str, fmt, args) < 0 || str == NULL) { + HEIMDAL_MUTEX_unlock(context->mutex); + return; + } if (context->error_string) { int e; e = asprintf(&str2, "%s: %s", str, context->error_string); free(context->error_string); - if (e < 0) + if (e < 0 || str2 == NULL) context->error_string = NULL; else context->error_string = str2; @@ -241,7 +250,7 @@ krb5_get_error_message(krb5_context context, krb5_error_code code) return strdup(msg); } - if (asprintf(&str, "<unknown error: %d>", (int)code) == -1) + if (asprintf(&str, "<unknown error: %d>", (int)code) == -1 || str == NULL) return NULL; return str; diff --git a/source4/heimdal/lib/krb5/expand_path.c b/source4/heimdal/lib/krb5/expand_path.c new file mode 100644 index 0000000000..70096e1c7a --- /dev/null +++ b/source4/heimdal/lib/krb5/expand_path.c @@ -0,0 +1,500 @@ + +/*********************************************************************** + * Copyright (c) 2009, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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" + +typedef int PTYPE; + +#ifdef _WIN32 +#include <shlobj.h> +#include <sddl.h> + +/* + * Expand a %{TEMP} token + * + * The %{TEMP} token expands to the temporary path for the current + * user as returned by GetTempPath(). + * + * @note: Since the GetTempPath() function relies on the TMP or TEMP + * environment variables, this function will failover to the system + * temporary directory until the user profile is loaded. In addition, + * the returned path may or may not exist. + */ +static int +_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + TCHAR tpath[MAX_PATH]; + size_t len; + + if (!GetTempPath(sizeof(tpath)/sizeof(tpath[0]), tpath)) { + if (context) + krb5_set_error_message(context, EINVAL, + "Failed to get temporary path (GLE=%d)", + GetLastError()); + return EINVAL; + } + + len = strlen(tpath); + + if (len > 0 && tpath[len - 1] == '\\') + tpath[len - 1] = '\0'; + + *ret = strdup(tpath); + + if (*ret == NULL) { + if (context) + krb5_set_error_message(context, ENOMEM, "strdup - Out of memory"); + return ENOMEM; + } + + return 0; +} + +extern HINSTANCE _krb5_hInstance; + +/* + * Expand a %{BINDIR} token + * + * This is also used to expand a few other tokens on Windows, since + * most of the executable binaries end up in the same directory. The + * "bin" directory is considered to be the directory in which the + * krb5.dll is located. + */ +static int +_expand_bin_dir(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + TCHAR path[MAX_PATH]; + TCHAR *lastSlash; + DWORD nc; + + nc = GetModuleFileName(_krb5_hInstance, path, sizeof(path)/sizeof(path[0])); + if (nc == 0 || + nc == sizeof(path)/sizeof(path[0])) { + return EINVAL; + } + + lastSlash = strrchr(path, '\\'); + if (lastSlash != NULL) { + TCHAR *fslash = strrchr(lastSlash, '/'); + + if (fslash != NULL) + lastSlash = fslash; + + *lastSlash = '\0'; + } + + if (postfix) { + if (strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) + return EINVAL; + } + + *ret = strdup(path); + if (*ret == NULL) + return ENOMEM; + + return 0; +} + +/* + * Expand a %{USERID} token + * + * The %{USERID} token expands to the string representation of the + * user's SID. The user account that will be used is the account + * corresponding to the current thread's security token. This means + * that: + * + * - If the current thread token has the anonymous impersonation + * level, the call will fail. + * + * - If the current thread is impersonating a token at + * SecurityIdentification level the call will fail. + * + */ +static int +_expand_userid(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + int rv = EINVAL; + HANDLE hThread = NULL; + HANDLE hToken = NULL; + PTOKEN_OWNER pOwner = NULL; + DWORD len = 0; + LPTSTR strSid = NULL; + + hThread = GetCurrentThread(); + + if (!OpenThreadToken(hThread, TOKEN_QUERY, + FALSE, /* Open the thread token as the + current thread user. */ + &hToken)) { + + DWORD le = GetLastError(); + + if (le == ERROR_NO_TOKEN) { + HANDLE hProcess = GetCurrentProcess(); + + le = 0; + if (!OpenProcessToken(hProcess, TOKEN_QUERY, &hToken)) + le = GetLastError(); + } + + if (le != 0) { + if (context) + krb5_set_error_message(context, rv, + "Can't open thread token (GLE=%d)", le); + goto _exit; + } + } + + if (!GetTokenInformation(hToken, TokenOwner, NULL, 0, &len)) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + if (context) + krb5_set_error_message(context, rv, + "Unexpected error reading token information (GLE=%d)", + GetLastError()); + goto _exit; + } + + if (len == 0) { + if (context) + krb5_set_error_message(context, rv, + "GetTokenInformation() returned truncated buffer"); + goto _exit; + } + + pOwner = malloc(len); + if (pOwner == NULL) { + if (context) + krb5_set_error_message(context, rv, "Out of memory"); + goto _exit; + } + } else { + if (context) + krb5_set_error_message(context, rv, "GetTokenInformation() returned truncated buffer"); + goto _exit; + } + + if (!GetTokenInformation(hToken, TokenOwner, pOwner, len, &len)) { + if (context) + krb5_set_error_message(context, rv, "GetTokenInformation() failed. GLE=%d", GetLastError()); + goto _exit; + } + + if (!ConvertSidToStringSid(pOwner->Owner, &strSid)) { + if (context) + krb5_set_error_message(context, rv, "Can't convert SID to string. GLE=%d", GetLastError()); + goto _exit; + } + + *ret = strdup(strSid); + if (*ret == NULL && context) + krb5_set_error_message(context, rv, "Out of memory"); + + rv = 0; + + _exit: + if (hToken != NULL) + CloseHandle(hToken); + + if (pOwner != NULL) + free (pOwner); + + if (strSid != NULL) + LocalFree(strSid); + + return rv; +} + +/* + * Expand a folder identified by a CSIDL + */ + +static int +_expand_csidl(krb5_context context, PTYPE folder, const char *postfix, char **ret) +{ + TCHAR path[MAX_PATH]; + size_t len; + + if (SHGetFolderPath(NULL, folder, NULL, SHGFP_TYPE_CURRENT, path) != S_OK) { + if (context) + krb5_set_error_message(context, EINVAL, "Unable to determine folder path"); + return EINVAL; + } + + len = strlen(path); + + if (len > 0 && path[len - 1] == '\\') + path[len - 1] = '\0'; + + if (postfix && + strlcat(path, postfix, sizeof(path)/sizeof(path[0])) >= sizeof(path)/sizeof(path[0])) { + return ENOMEM; + } + + *ret = strdup(path); + if (*ret == NULL) { + if (context) + krb5_set_error_message(context, ENOMEM, "Out of memory"); + return ENOMEM; + } + return 0; +} + +#else + +static int +_expand_path(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + *ret = strdup(postfix); + if (*ret == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc - out of memory"); + return ENOMEM; + } + return 0; +} + +static int +_expand_temp_folder(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + const char *p = NULL; + + if (issuid()) + p = getenv("TEMP"); + if (p) + *ret = strdup(p); + else + *ret = strdup("/tmp"); + if (*ret == NULL) + return ENOMEM; + return 0; +} + +static int +_expand_userid(krb5_context context, PTYPE param, const char *postfix, char **str) +{ + int ret = asprintf(str, "%ld", (unsigned long)getuid()); + if (ret < 0 || *str == NULL) + return ENOMEM; + return 0; +} + + +#endif /* _WIN32 */ + +/** + * Expand a %{null} token + * + * The expansion of a %{null} token is always the empty string. + */ + +static int +_expand_null(krb5_context context, PTYPE param, const char *postfix, char **ret) +{ + *ret = strdup(""); + if (*ret == NULL) { + if (context) + krb5_set_error_message(context, ENOMEM, "Out of memory"); + return ENOMEM; + } + return 0; +} + + +static const struct token { + const char * tok; + int ftype; +#define FTYPE_CSIDL 0 +#define FTYPE_SPECIAL 1 + + PTYPE param; + const char * postfix; + + int (*exp_func)(krb5_context, PTYPE, const char *, char **); + +#define SPECIALP(f, P) FTYPE_SPECIAL, 0, P, f +#define SPECIAL(f) SPECIALP(f, NULL) + +} tokens[] = { +#ifdef _WIN32 +#define CSIDLP(C,P) FTYPE_CSIDL, C, P, _expand_csidl +#define CSIDL(C) CSIDLP(C, NULL) + + {"APPDATA", CSIDL(CSIDL_APPDATA)}, /* Roaming application data (for current user) */ + {"COMMON_APPDATA", CSIDL(CSIDL_COMMON_APPDATA)}, /* Application data (all users) */ + {"LOCAL_APPDATA", CSIDL(CSIDL_LOCAL_APPDATA)}, /* Local application data (for current user) */ + {"SYSTEM", CSIDL(CSIDL_SYSTEM)}, /* Windows System folder (e.g. %WINDIR%\System32) */ + {"WINDOWS", CSIDL(CSIDL_WINDOWS)}, /* Windows folder */ + {"USERCONFIG", CSIDLP(CSIDL_APPDATA, "\\" PACKAGE)}, /* Per user Heimdal configuration file path */ + {"COMMONCONFIG", CSIDLP(CSIDL_COMMON_APPDATA, "\\" PACKAGE)}, /* Common Heimdal configuration file path */ + {"LIBDIR", SPECIAL(_expand_bin_dir)}, + {"BINDIR", SPECIAL(_expand_bin_dir)}, + {"LIBEXEC", SPECIAL(_expand_bin_dir)}, + {"SBINDIR", SPECIAL(_expand_bin_dir)}, +#else + {"LIBDIR", FTYPE_SPECIAL, 0, LIBDIR, _expand_path}, + {"BINDIR", FTYPE_SPECIAL, 0, BINDIR, _expand_path}, + {"LIBEXEC", FTYPE_SPECIAL, 0, LIBEXECDIR, _expand_path}, + {"SBINDIR", FTYPE_SPECIAL, 0, SBINDIR, _expand_path}, +#endif + {"TEMP", SPECIAL(_expand_temp_folder)}, + {"USERID", SPECIAL(_expand_userid)}, + {"uid", SPECIAL(_expand_userid)}, + {"null", SPECIAL(_expand_null)} +}; + +static int +_expand_token(krb5_context context, + const char *token, + const char *token_end, + char **ret) +{ + size_t i; + + *ret = NULL; + + if (token[0] != '%' || token[1] != '{' || token_end[0] != '}' || + token_end - token <= 2) { + if (context) + krb5_set_error_message(context, EINVAL,"Invalid token."); + return EINVAL; + } + + for (i = 0; i < sizeof(tokens)/sizeof(tokens[0]); i++) { + if (!strncmp(token+2, tokens[i].tok, (token_end - token) - 2)) + return tokens[i].exp_func(context, tokens[i].param, + tokens[i].postfix, ret); + } + + if (context) + krb5_set_error_message(context, EINVAL, "Invalid token."); + return EINVAL; +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +_krb5_expand_path_tokens(krb5_context context, + const char *path_in, + char **ppath_out) +{ + char *tok_begin, *tok_end, *append; + const char *path_left; + size_t len = 0; + + if (path_in == NULL || *path_in == '\0') { + *ppath_out = strdup(""); + return 0; + } + + *ppath_out = NULL; + + for (path_left = path_in; path_left && *path_left; ) { + + tok_begin = strstr(path_left, "%{"); + + if (tok_begin && tok_begin != path_left) { + + append = malloc((tok_begin - path_left) + 1); + if (append) { + memcpy(append, path_left, tok_begin - path_left); + append[tok_begin - path_left] = '\0'; + } + path_left = tok_begin; + + } else if (tok_begin) { + + tok_end = strchr(tok_begin, '}'); + if (tok_end == NULL) { + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + if (context) + krb5_set_error_message(context, EINVAL, "variable missing }"); + return EINVAL; + } + + if (_expand_token(context, tok_begin, tok_end, &append)) { + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + return EINVAL; + } + + path_left = tok_end + 1; + } else { + + append = strdup(path_left); + path_left = NULL; + + } + + if (append == NULL) { + + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + if (context) + krb5_set_error_message(context, ENOMEM, "malloc - out of memory"); + return ENOMEM; + + } + + { + size_t append_len = strlen(append); + char * new_str = realloc(*ppath_out, len + append_len + 1); + + if (new_str == NULL) { + free(append); + if (*ppath_out) + free(*ppath_out); + *ppath_out = NULL; + if (context) + krb5_set_error_message(context, ENOMEM, "malloc - out of memory"); + return ENOMEM; + } + + *ppath_out = new_str; + memcpy(*ppath_out + len, append, append_len + 1); + len = len + append_len; + free(append); + } + } + +#ifdef _WIN32 + /* Also deal with slashes */ + if (*ppath_out) { + char * c; + for (c = *ppath_out; *c; c++) + if (*c == '/') + *c = '\\'; + } +#endif + + return 0; +} diff --git a/source4/heimdal/lib/krb5/fcache.c b/source4/heimdal/lib/krb5/fcache.c index 67c4c74444..218bd2cdbf 100644 --- a/source4/heimdal/lib/krb5/fcache.c +++ b/source4/heimdal/lib/krb5/fcache.c @@ -58,7 +58,7 @@ struct fcc_cursor { #define FCC_CURSOR(C) ((struct fcc_cursor*)(C)) -static const char* +static const char* KRB5_CALLCONV fcc_get_name(krb5_context context, krb5_ccache id) { @@ -167,20 +167,20 @@ write_storage(krb5_context context, krb5_storage *sp, int fd) } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_lock(krb5_context context, krb5_ccache id, int fd, krb5_boolean exclusive) { return _krb5_xlock(context, fd, exclusive, fcc_get_name(context, id)); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_unlock(krb5_context context, int fd) { return _krb5_xunlock(context, fd); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_resolve(krb5_context context, krb5_ccache *id, const char *res) { krb5_fcache *f; @@ -304,12 +304,13 @@ _krb5_erase_file(krb5_context context, const char *filename) return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_gen_new(krb5_context context, krb5_ccache *id) { + char *file = NULL, *exp_file = NULL; + krb5_error_code ret; krb5_fcache *f; int fd; - char *file; f = malloc(sizeof(*f)); if(f == NULL) { @@ -317,39 +318,30 @@ fcc_gen_new(krb5_context context, krb5_ccache *id) N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } - asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); - if(file == NULL) { + ret = asprintf (&file, "%sXXXXXX", KRB5_DEFAULT_CCFILE_ROOT); + if(ret < 0 || file == NULL) { free(f); krb5_set_error_message(context, KRB5_CC_NOMEM, N_("malloc: out of memory", "")); return KRB5_CC_NOMEM; } -#ifdef KRB5_USE_PATH_TOKENS - { - char * exp_file = NULL; - krb5_error_code ec; + ret = _krb5_expand_path_tokens(context, file, &exp_file); + free(file); + if (ret) + return ret; - ec = _krb5_expand_path_tokens(context, file, &exp_file); + file = exp_file; - if (ec == 0) { - free(file); - file = exp_file; - } else { - free(file); - return ec; - } - } -#endif - fd = mkstemp(file); + fd = mkstemp(exp_file); if(fd < 0) { int ret = errno; - krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), file); + krb5_set_error_message(context, ret, N_("mkstemp %s failed", ""), exp_file); free(f); - free(file); + free(exp_file); return ret; } close(fd); - f->filename = file; + f->filename = exp_file; f->version = 0; (*id)->data.data = f; (*id)->data.length = sizeof(*f); @@ -381,7 +373,7 @@ storage_set_flags(krb5_context context, krb5_storage *sp, int vno) krb5_storage_set_flags(sp, flags); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_open(krb5_context context, krb5_ccache id, int *fd_ret, @@ -412,7 +404,7 @@ fcc_open(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) @@ -468,7 +460,7 @@ fcc_initialize(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_close(krb5_context context, krb5_ccache id) { @@ -477,7 +469,7 @@ fcc_close(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_destroy(krb5_context context, krb5_ccache id) { @@ -485,7 +477,7 @@ fcc_destroy(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) @@ -675,7 +667,7 @@ init_fcc (krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) @@ -696,12 +688,12 @@ fcc_get_principal(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_end_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor); -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_first (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -734,7 +726,7 @@ fcc_get_first (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, @@ -752,7 +744,7 @@ fcc_get_next (krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_end_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -764,7 +756,7 @@ fcc_end_get (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags which, @@ -772,7 +764,7 @@ fcc_remove_cred(krb5_context context, { krb5_error_code ret; krb5_ccache copy, newfile; - char *newname; + char *newname = NULL; int fd; ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, ©); @@ -791,10 +783,10 @@ fcc_remove_cred(krb5_context context, return ret; } - asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id)); - if (newname == NULL) { + ret = asprintf(&newname, "FILE:%s.XXXXXX", FILENAME(id)); + if (ret < 0 || newname == NULL) { krb5_cc_destroy(context, copy); - return ret; + return ENOMEM; } fd = mkstemp(&newname[5]); @@ -821,7 +813,7 @@ fcc_remove_cred(krb5_context context, return ret; } - ret = rename(&newname[5], FILENAME(id)); + ret = rk_rename(&newname[5], FILENAME(id)); if (ret) ret = errno; free(newname); @@ -830,7 +822,7 @@ fcc_remove_cred(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) @@ -838,7 +830,7 @@ fcc_set_flags(krb5_context context, return 0; /* XXX */ } -static int +static int KRB5_CALLCONV fcc_get_version(krb5_context context, krb5_ccache id) { @@ -849,7 +841,7 @@ struct fcache_iter { int first; }; -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) { struct fcache_iter *iter; @@ -864,7 +856,7 @@ fcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) { struct fcache_iter *iter = cursor; @@ -904,7 +896,7 @@ fcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) { struct fcache_iter *iter = cursor; @@ -912,20 +904,12 @@ fcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_error_code ret = 0; - ret = rename(FILENAME(from), FILENAME(to)); -#ifdef RENAME_DOES_NOT_UNLINK - if (ret && (errno == EEXIST || errno == EACCES)) { - ret = unlink(FILENAME(to)); - if (ret == 0) { - ret = rename(FILENAME(from), FILENAME(to)); - } - } -#endif + ret = rk_rename(FILENAME(from), FILENAME(to)); if (ret && errno != EXDEV) { char buf[128]; @@ -990,11 +974,12 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_storage *sp; int fd; - ret = init_fcc (context, to, &sp, &fd, NULL); - if (sp) - krb5_storage_free(sp); - fcc_unlock(context, fd); - close(fd); + if ((ret = init_fcc (context, to, &sp, &fd, NULL)) == 0) { + if (sp) + krb5_storage_free(sp); + fcc_unlock(context, fd); + close(fd); + } } fcc_close(context, from); @@ -1002,7 +987,7 @@ fcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_default_name(krb5_context context, char **str) { return _krb5_expand_default_cc_name(context, @@ -1010,7 +995,7 @@ fcc_get_default_name(krb5_context context, char **str) str); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) { krb5_error_code ret; @@ -1031,17 +1016,17 @@ fcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset) { return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset) { krb5_error_code ret; - krb5_storage *sp; + krb5_storage *sp = NULL; int fd; ret = init_fcc(context, id, &sp, &fd, kdc_offset); if (sp) diff --git a/source4/heimdal/lib/krb5/generate_seq_number.c b/source4/heimdal/lib/krb5/generate_seq_number.c index 575f842d8b..6001d69261 100644 --- a/source4/heimdal/lib/krb5/generate_seq_number.c +++ b/source4/heimdal/lib/krb5/generate_seq_number.c @@ -38,7 +38,7 @@ krb5_generate_seq_number(krb5_context context, const krb5_keyblock *key, uint32_t *seqno) { - if (RAND_bytes((void *)seqno, sizeof(*seqno)) != 1) + if (RAND_bytes((void *)seqno, sizeof(*seqno)) <= 0) krb5_abortx(context, "Failed to generate random block"); /* MIT used signed numbers, lets not stomp into that space directly */ *seqno &= 0x3fffffff; diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 75e44f0cd4..8f9d462190 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -314,7 +314,7 @@ _krb5_get_krbtgt(krb5_context context, } /* DCE compatible decrypt proc */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV decrypt_tkt_with_subkey (krb5_context context, krb5_keyblock *key, krb5_key_usage usage, @@ -939,9 +939,9 @@ get_cred_kdc_referral(krb5_context context, ret = EINVAL; if (ret) { - ret = get_cred_kdc_address (context, ccache, flags, NULL, - &referral, &tgt, impersonate_principal, - second_ticket, &ticket); + ret = get_cred_kdc_address(context, ccache, flags, NULL, + &referral, &tgt, impersonate_principal, + second_ticket, &ticket); if (ret) goto out; } @@ -956,8 +956,8 @@ get_cred_kdc_referral(krb5_context context, krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US, N_("Got back an non krbtgt " "ticket referrals", "")); - krb5_free_cred_contents(context, &ticket); - return KRB5KRB_AP_ERR_NOT_US; + ret = KRB5KRB_AP_ERR_NOT_US; + goto out; } referral_realm = ticket.server->name.name_string.val[1]; @@ -979,8 +979,8 @@ get_cred_kdc_referral(krb5_context context, "loops back to realm %s", ""), tgt.server->realm, referral_realm); - krb5_free_cred_contents(context, &ticket); - return KRB5_GET_IN_TKT_LOOP; + ret = KRB5_GET_IN_TKT_LOOP; + goto out; } tickets++; } @@ -996,10 +996,8 @@ get_cred_kdc_referral(krb5_context context, } ret = add_cred(context, &ticket, ret_tgts); - if (ret) { - krb5_free_cred_contents(context, &ticket); + if (ret) goto out; - } /* try realm in the referral */ ret = krb5_principal_set_realm(context, @@ -1017,6 +1015,7 @@ get_cred_kdc_referral(krb5_context context, out: krb5_free_principal(context, referral.server); krb5_free_cred_contents(context, &tgt); + krb5_free_cred_contents(context, &ticket); return ret; } diff --git a/source4/heimdal/lib/krb5/get_default_principal.c b/source4/heimdal/lib/krb5/get_default_principal.c index 539dedfa47..ba4301ce29 100644 --- a/source4/heimdal/lib/krb5/get_default_principal.c +++ b/source4/heimdal/lib/krb5/get_default_principal.c @@ -104,8 +104,6 @@ krb5_error_code _krb5_get_default_principal_local(krb5_context context, krb5_principal *princ) { - krb5_error_code ret = 0; - /* See if we can get the principal first. We only expect this to work if logged into a domain. */ { diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index f443788075..869687aa63 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -94,7 +94,7 @@ free_paid(krb5_context context, struct pa_info_data *ppaid) krb5_free_data(context, ppaid->s2kparams); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV default_s2k_func(krb5_context context, krb5_enctype type, krb5_const_pointer keyseed, krb5_salt salt, krb5_data *s2kparms, @@ -234,11 +234,12 @@ report_expiration (krb5_context context, const char *str, time_t now) { - char *p; + char *p = NULL; - asprintf (&p, "%s%s", str, ctime(&now)); - (*prompter) (context, data, NULL, p, 0, NULL); - free (p); + if (asprintf(&p, "%s%s", str, ctime(&now)) < 0 || p == NULL) + return; + (*prompter)(context, data, NULL, p, 0, NULL); + free(p); } /* @@ -562,10 +563,14 @@ change_password (krb5_context context, &result_string); if (ret) goto out; - asprintf (&p, "%s: %.*s\n", - result_code ? "Error" : "Success", - (int)result_string.length, - result_string.length > 0 ? (char*)result_string.data : ""); + if (asprintf(&p, "%s: %.*s\n", + result_code ? "Error" : "Success", + (int)result_string.length, + result_string.length > 0 ? (char*)result_string.data : "") < 0) + { + ret = ENOMEM; + goto out; + } /* return the result */ (*prompter) (context, data, NULL, p, 0, NULL); @@ -1454,7 +1459,7 @@ krb5_init_creds_set_password(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV keytab_key_proc(krb5_context context, krb5_enctype enctype, krb5_const_pointer keyseed, krb5_salt salt, krb5_data *s2kparms, @@ -1581,7 +1586,7 @@ krb5_init_creds_set_keytab(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV keyblock_key_proc(krb5_context context, krb5_enctype enctype, krb5_const_pointer keyseed, krb5_salt salt, krb5_data *s2kparms, @@ -1613,7 +1618,8 @@ krb5_init_creds_set_keyblock(krb5_context context, * @param in input data from KDC, first round it should be reset by krb5_data_zer(). * @param out reply to KDC. * @param hostinfo KDC address info, first round it can be NULL. - * @param flags status of the round, if 1 is set, continue one more round. + * @param flags status of the round, if + * KRB5_INIT_CREDS_STEP_FLAG_CONTINUE is set, continue one more round. * * @return 0 for success, or an Kerberos 5 error code, see * krb5_get_error_message(). @@ -1816,7 +1822,7 @@ krb5_init_creds_step(krb5_context context, out->data = ctx->req_buffer.data; out->length = ctx->req_buffer.length; - *flags = 1; + *flags = KRB5_INIT_CREDS_STEP_FLAG_CONTINUE; return 0; out: diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index 01ea184773..80a72ecbf7 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -1205,94 +1205,6 @@ _krb5_kcm_noop(krb5_context context, /* * Request: * NameZ - * Mode - * - * Response: - * - */ -krb5_error_code -_krb5_kcm_chmod(krb5_context context, - krb5_ccache id, - uint16_t mode) -{ - krb5_error_code ret; - krb5_kcmcache *k = KCMCACHE(id); - krb5_storage *request; - - ret = krb5_kcm_storage_request(context, KCM_OP_CHMOD, &request); - if (ret) - return ret; - - ret = krb5_store_stringz(request, k->name); - if (ret) { - krb5_storage_free(request); - return ret; - } - - ret = krb5_store_int16(request, mode); - if (ret) { - krb5_storage_free(request); - return ret; - } - - ret = krb5_kcm_call(context, request, NULL, NULL); - - krb5_storage_free(request); - return ret; -} - - -/* - * Request: - * NameZ - * UID - * GID - * - * Response: - * - */ -krb5_error_code -_krb5_kcm_chown(krb5_context context, - krb5_ccache id, - uint32_t uid, - uint32_t gid) -{ - krb5_error_code ret; - krb5_kcmcache *k = KCMCACHE(id); - krb5_storage *request; - - ret = krb5_kcm_storage_request(context, KCM_OP_CHOWN, &request); - if (ret) - return ret; - - ret = krb5_store_stringz(request, k->name); - if (ret) { - krb5_storage_free(request); - return ret; - } - - ret = krb5_store_int32(request, uid); - if (ret) { - krb5_storage_free(request); - return ret; - } - - ret = krb5_store_int32(request, gid); - if (ret) { - krb5_storage_free(request); - return ret; - } - - ret = krb5_kcm_call(context, request, NULL, NULL); - - krb5_storage_free(request); - return ret; -} - - -/* - * Request: - * NameZ * ServerPrincipalPresent * ServerPrincipal OPTIONAL * Key diff --git a/source4/heimdal/lib/krb5/keytab.c b/source4/heimdal/lib/krb5/keytab.c index 79b079a056..d1ffd57738 100644 --- a/source4/heimdal/lib/krb5/keytab.c +++ b/source4/heimdal/lib/krb5/keytab.c @@ -73,11 +73,6 @@ * store the keytab in a AFS keyfile (usually /usr/afs/etc/KeyFile ), * the type's name is AFSKEYFILE. The residual part is a filename. * - * - krb4 - * the keytab is a Kerberos 4 srvtab that is on-the-fly converted to - * a keytab. The type's name is krb4 The residual part is a - * filename. - * * - memory * The keytab is stored in a memory segment. This allows sensitive * and/or temporary data not to be stored on disk. The type's name @@ -113,7 +108,7 @@ main (int argc, char **argv) if (ret) krb5_err(context, 1, ret, "krb5_kt_start_seq_get"); while((ret = krb5_kt_next_entry(context, keytab, &entry, &cursor)) == 0){ - krb5_unparse_name_short(context, entry.principal, &principal); + krb5_unparse_name(context, entry.principal, &principal); printf("principal: %s\n", principal); free(principal); krb5_kt_free_entry(context, &entry); diff --git a/source4/heimdal/lib/krb5/keytab_any.c b/source4/heimdal/lib/krb5/keytab_any.c index 02de8c8028..d056964769 100644 --- a/source4/heimdal/lib/krb5/keytab_any.c +++ b/source4/heimdal/lib/krb5/keytab_any.c @@ -53,7 +53,7 @@ free_list (krb5_context context, struct any_data *a) } } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_resolve(krb5_context context, const char *name, krb5_keytab id) { struct any_data *a, *a0 = NULL, *prev = NULL; @@ -95,7 +95,7 @@ any_resolve(krb5_context context, const char *name, krb5_keytab id) return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_get_name (krb5_context context, krb5_keytab id, char *name, @@ -106,7 +106,7 @@ any_get_name (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_close (krb5_context context, krb5_keytab id) { @@ -121,7 +121,7 @@ struct any_cursor_extra_data { krb5_kt_cursor cursor; }; -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *c) @@ -150,7 +150,7 @@ any_start_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_next_entry (krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, @@ -182,7 +182,7 @@ any_next_entry (krb5_context context, } while (1); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_end_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) @@ -198,7 +198,7 @@ any_end_seq_get(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) @@ -218,7 +218,7 @@ any_add_entry(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV any_remove_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index 9a21db0cbb..2b9ea7f11d 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -286,7 +286,7 @@ krb5_kt_store_principal(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_resolve(krb5_context context, const char *name, krb5_keytab id) { struct fkt_data *d; @@ -307,7 +307,7 @@ fkt_resolve(krb5_context context, const char *name, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id) { krb5_error_code ret; @@ -320,7 +320,7 @@ fkt_resolve_java14(krb5_context context, const char *name, krb5_keytab id) return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_close(krb5_context context, krb5_keytab id) { struct fkt_data *d = id->data; @@ -329,7 +329,7 @@ fkt_close(krb5_context context, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_destroy(krb5_context context, krb5_keytab id) { struct fkt_data *d = id->data; @@ -337,7 +337,7 @@ fkt_destroy(krb5_context context, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_get_name(krb5_context context, krb5_keytab id, char *name, @@ -430,7 +430,7 @@ fkt_start_seq_get_int(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *c) @@ -503,7 +503,7 @@ loop: return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_next_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, @@ -512,7 +512,7 @@ fkt_next_entry(krb5_context context, return fkt_next_entry_int(context, id, entry, cursor, NULL, NULL); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_end_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) @@ -523,7 +523,7 @@ fkt_end_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_setup_keytab(krb5_context context, krb5_keytab id, krb5_storage *sp) @@ -537,7 +537,7 @@ fkt_setup_keytab(krb5_context context, return krb5_store_int8 (sp, id->version); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) @@ -723,7 +723,7 @@ fkt_add_entry(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV fkt_remove_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) diff --git a/source4/heimdal/lib/krb5/keytab_keyfile.c b/source4/heimdal/lib/krb5/keytab_keyfile.c index 54666c7d44..28bbaeee8c 100644 --- a/source4/heimdal/lib/krb5/keytab_keyfile.c +++ b/source4/heimdal/lib/krb5/keytab_keyfile.c @@ -128,7 +128,7 @@ get_cell_and_realm (krb5_context context, struct akf_data *d) * init and get filename */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_resolve(krb5_context context, const char *name, krb5_keytab id) { int ret; @@ -164,7 +164,7 @@ akf_resolve(krb5_context context, const char *name, krb5_keytab id) * cleanup */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_close(krb5_context context, krb5_keytab id) { struct akf_data *d = id->data; @@ -179,7 +179,7 @@ akf_close(krb5_context context, krb5_keytab id) * Return filename */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_get_name(krb5_context context, krb5_keytab id, char *name, @@ -195,7 +195,7 @@ akf_get_name(krb5_context context, * Init */ -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *c) @@ -226,7 +226,7 @@ akf_start_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_next_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, @@ -281,7 +281,7 @@ akf_next_entry(krb5_context context, return ret; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_end_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) @@ -291,7 +291,7 @@ akf_end_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV akf_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) diff --git a/source4/heimdal/lib/krb5/keytab_memory.c b/source4/heimdal/lib/krb5/keytab_memory.c index 73ffa1c67d..0ee684d363 100644 --- a/source4/heimdal/lib/krb5/keytab_memory.c +++ b/source4/heimdal/lib/krb5/keytab_memory.c @@ -50,7 +50,7 @@ static HEIMDAL_MUTEX mkt_mutex = HEIMDAL_MUTEX_INITIALIZER; static struct mkt_data *mkt_head; -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_resolve(krb5_context context, const char *name, krb5_keytab id) { struct mkt_data *d; @@ -95,7 +95,7 @@ mkt_resolve(krb5_context context, const char *name, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_close(krb5_context context, krb5_keytab id) { struct mkt_data *d = id->data, **dp; @@ -126,7 +126,7 @@ mkt_close(krb5_context context, krb5_keytab id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_get_name(krb5_context context, krb5_keytab id, char *name, @@ -137,7 +137,7 @@ mkt_get_name(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_start_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *c) @@ -147,7 +147,7 @@ mkt_start_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_next_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, @@ -159,7 +159,7 @@ mkt_next_entry(krb5_context context, return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_end_seq_get(krb5_context context, krb5_keytab id, krb5_kt_cursor *cursor) @@ -167,7 +167,7 @@ mkt_end_seq_get(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_add_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) @@ -185,7 +185,7 @@ mkt_add_entry(krb5_context context, &d->entries[d->num_entries++]); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mkt_remove_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry) diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index c810b8bc74..8f4210e19b 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -63,6 +63,12 @@ #endif #endif +#ifdef _WIN32 +#define KRB5_CALLCONV __stdcall +#else +#define KRB5_CALLCONV +#endif + /* simple constants */ #ifndef TRUE @@ -404,6 +410,10 @@ typedef union { #define KRB5_TC_MATCH_2ND_TKT (1 << 23) #define KRB5_TC_MATCH_IS_SKEY (1 << 22) +/* constants for get_flags and set_flags */ +#define KRB5_TC_OPENCLOSE 0x00000001 +#define KRB5_TC_NOTICKET 0x00000002 + typedef AuthorizationData krb5_authdata; typedef KRB_ERROR krb5_error; @@ -427,33 +437,34 @@ typedef struct krb5_cc_cache_cursor_data *krb5_cc_cache_cursor; 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 *); - krb5_error_code (*gen_new)(krb5_context, krb5_ccache *); - krb5_error_code (*init)(krb5_context, krb5_ccache, krb5_principal); - krb5_error_code (*destroy)(krb5_context, krb5_ccache); - krb5_error_code (*close)(krb5_context, krb5_ccache); - krb5_error_code (*store)(krb5_context, krb5_ccache, krb5_creds*); - krb5_error_code (*retrieve)(krb5_context, krb5_ccache, - krb5_flags, const krb5_creds*, krb5_creds *); - krb5_error_code (*get_princ)(krb5_context, krb5_ccache, krb5_principal*); - krb5_error_code (*get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *); - krb5_error_code (*get_next)(krb5_context, krb5_ccache, - krb5_cc_cursor*, krb5_creds*); - krb5_error_code (*end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*); - krb5_error_code (*remove_cred)(krb5_context, krb5_ccache, - krb5_flags, krb5_creds*); - krb5_error_code (*set_flags)(krb5_context, krb5_ccache, krb5_flags); - int (*get_version)(krb5_context, krb5_ccache); - krb5_error_code (*get_cache_first)(krb5_context, krb5_cc_cursor *); - krb5_error_code (*get_cache_next)(krb5_context, krb5_cc_cursor, krb5_ccache *); - krb5_error_code (*end_cache_get)(krb5_context, krb5_cc_cursor); - krb5_error_code (*move)(krb5_context, krb5_ccache, krb5_ccache); - krb5_error_code (*get_default_name)(krb5_context, char **); - krb5_error_code (*set_default)(krb5_context, krb5_ccache); - krb5_error_code (*lastchange)(krb5_context, krb5_ccache, krb5_timestamp *); - krb5_error_code (*set_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat); - krb5_error_code (*get_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat *); + const char* (KRB5_CALLCONV * get_name)(krb5_context, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * resolve)(krb5_context, krb5_ccache *, const char *); + krb5_error_code (KRB5_CALLCONV * gen_new)(krb5_context, krb5_ccache *); + krb5_error_code (KRB5_CALLCONV * init)(krb5_context, krb5_ccache, krb5_principal); + krb5_error_code (KRB5_CALLCONV * destroy)(krb5_context, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * close)(krb5_context, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * store)(krb5_context, krb5_ccache, krb5_creds*); + krb5_error_code (KRB5_CALLCONV * retrieve)(krb5_context, krb5_ccache, + krb5_flags, const krb5_creds*, krb5_creds *); + krb5_error_code (KRB5_CALLCONV * get_princ)(krb5_context, krb5_ccache, krb5_principal*); + krb5_error_code (KRB5_CALLCONV * get_first)(krb5_context, krb5_ccache, krb5_cc_cursor *); + krb5_error_code (KRB5_CALLCONV * get_next)(krb5_context, krb5_ccache, + krb5_cc_cursor*, krb5_creds*); + krb5_error_code (KRB5_CALLCONV * end_get)(krb5_context, krb5_ccache, krb5_cc_cursor*); + krb5_error_code (KRB5_CALLCONV * remove_cred)(krb5_context, krb5_ccache, + krb5_flags, krb5_creds*); + krb5_error_code (KRB5_CALLCONV * set_flags)(krb5_context, krb5_ccache, krb5_flags); + int (KRB5_CALLCONV * get_version)(krb5_context, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * get_cache_first)(krb5_context, krb5_cc_cursor *); + krb5_error_code (KRB5_CALLCONV * get_cache_next)(krb5_context, krb5_cc_cursor, + krb5_ccache *); + krb5_error_code (KRB5_CALLCONV * end_cache_get)(krb5_context, krb5_cc_cursor); + krb5_error_code (KRB5_CALLCONV * move)(krb5_context, krb5_ccache, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * get_default_name)(krb5_context, char **); + krb5_error_code (KRB5_CALLCONV * set_default)(krb5_context, krb5_ccache); + krb5_error_code (KRB5_CALLCONV * lastchange)(krb5_context, krb5_ccache, krb5_timestamp *); + krb5_error_code (KRB5_CALLCONV * set_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat); + krb5_error_code (KRB5_CALLCONV * get_kdc_offset)(krb5_context, krb5_ccache, krb5_deltat *); } krb5_cc_ops; struct krb5_log_facility; @@ -523,18 +534,18 @@ typedef struct krb5_keytab_data *krb5_keytab; struct krb5_keytab_data { const char *prefix; - krb5_error_code (*resolve)(krb5_context, const char*, krb5_keytab); - krb5_error_code (*get_name)(krb5_context, krb5_keytab, char*, size_t); - krb5_error_code (*close)(krb5_context, krb5_keytab); - krb5_error_code (*destroy)(krb5_context, krb5_keytab); - krb5_error_code (*get)(krb5_context, krb5_keytab, krb5_const_principal, - krb5_kvno, krb5_enctype, krb5_keytab_entry*); - krb5_error_code (*start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*); - krb5_error_code (*next_entry)(krb5_context, krb5_keytab, - krb5_keytab_entry*, krb5_kt_cursor*); - krb5_error_code (*end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*); - krb5_error_code (*add)(krb5_context, krb5_keytab, krb5_keytab_entry*); - krb5_error_code (*remove)(krb5_context, krb5_keytab, krb5_keytab_entry*); + krb5_error_code (KRB5_CALLCONV * resolve)(krb5_context, const char*, krb5_keytab); + krb5_error_code (KRB5_CALLCONV * get_name)(krb5_context, krb5_keytab, char*, size_t); + krb5_error_code (KRB5_CALLCONV * close)(krb5_context, krb5_keytab); + krb5_error_code (KRB5_CALLCONV * destroy)(krb5_context, krb5_keytab); + krb5_error_code (KRB5_CALLCONV * get)(krb5_context, krb5_keytab, krb5_const_principal, + krb5_kvno, krb5_enctype, krb5_keytab_entry*); + krb5_error_code (KRB5_CALLCONV * start_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*); + krb5_error_code (KRB5_CALLCONV * next_entry)(krb5_context, krb5_keytab, + krb5_keytab_entry*, krb5_kt_cursor*); + krb5_error_code (KRB5_CALLCONV * end_seq_get)(krb5_context, krb5_keytab, krb5_kt_cursor*); + krb5_error_code (KRB5_CALLCONV * add)(krb5_context, krb5_keytab, krb5_keytab_entry*); + krb5_error_code (KRB5_CALLCONV * remove)(krb5_context, krb5_keytab, krb5_keytab_entry*); void *data; int32_t version; }; @@ -606,8 +617,8 @@ typedef struct { extern const char *heimdal_version, *heimdal_long_version; -typedef void (*krb5_log_log_func_t)(const char*, const char*, void*); -typedef void (*krb5_log_close_func_t)(void*); +typedef void (KRB5_CALLCONV * krb5_log_log_func_t)(const char*, const char*, void*); +typedef void (KRB5_CALLCONV * krb5_log_close_func_t)(void*); typedef struct krb5_log_facility { char *program; @@ -642,28 +653,28 @@ typedef struct _krb5_prompt { krb5_prompt_type type; } krb5_prompt; -typedef int (*krb5_prompter_fct)(krb5_context /*context*/, - void * /*data*/, - const char * /*name*/, - const char * /*banner*/, - int /*num_prompts*/, - krb5_prompt /*prompts*/[]); -typedef krb5_error_code (*krb5_key_proc)(krb5_context /*context*/, - krb5_enctype /*type*/, - krb5_salt /*salt*/, - krb5_const_pointer /*keyseed*/, - krb5_keyblock ** /*key*/); -typedef krb5_error_code (*krb5_decrypt_proc)(krb5_context /*context*/, - krb5_keyblock * /*key*/, - krb5_key_usage /*usage*/, - krb5_const_pointer /*decrypt_arg*/, - krb5_kdc_rep * /*dec_rep*/); -typedef krb5_error_code (*krb5_s2k_proc)(krb5_context /*context*/, - krb5_enctype /*type*/, - krb5_const_pointer /*keyseed*/, - krb5_salt /*salt*/, - krb5_data * /*s2kparms*/, - krb5_keyblock ** /*key*/); +typedef int (KRB5_CALLCONV * krb5_prompter_fct)(krb5_context /*context*/, + void * /*data*/, + const char * /*name*/, + const char * /*banner*/, + int /*num_prompts*/, + krb5_prompt /*prompts*/[]); +typedef krb5_error_code (KRB5_CALLCONV * krb5_key_proc)(krb5_context /*context*/, + krb5_enctype /*type*/, + krb5_salt /*salt*/, + krb5_const_pointer /*keyseed*/, + krb5_keyblock ** /*key*/); +typedef krb5_error_code (KRB5_CALLCONV * krb5_decrypt_proc)(krb5_context /*context*/, + krb5_keyblock * /*key*/, + krb5_key_usage /*usage*/, + krb5_const_pointer /*decrypt_arg*/, + krb5_kdc_rep * /*dec_rep*/); +typedef krb5_error_code (KRB5_CALLCONV * krb5_s2k_proc)(krb5_context /*context*/, + krb5_enctype /*type*/, + krb5_const_pointer /*keyseed*/, + krb5_salt /*salt*/, + krb5_data * /*s2kparms*/, + krb5_keyblock ** /*key*/); struct _krb5_get_init_creds_opt_private; @@ -698,6 +709,9 @@ typedef struct _krb5_get_init_creds_opt krb5_get_init_creds_opt; #define KRB5_GET_INIT_CREDS_OPT_ANONYMOUS 0x0100 #define KRB5_GET_INIT_CREDS_OPT_DISABLE_TRANSITED_CHECK 0x0200 +/* krb5_init_creds_step flags argument */ +#define KRB5_INIT_CREDS_STEP_FLAG_CONTINUE 0x0001 + typedef struct _krb5_verify_init_creds_opt { krb5_flags flags; int ap_req_nofail; @@ -757,12 +771,9 @@ enum { KRB5_KRBHST_FLAGS_LARGE_MSG = 2 }; -typedef krb5_error_code (*krb5_send_to_kdc_func)(krb5_context, - void *, - krb5_krbhst_info *, - time_t, - const krb5_data *, - krb5_data *); +typedef krb5_error_code +(KRB5_CALLCONV * krb5_send_to_kdc_func)(krb5_context, void *, krb5_krbhst_info *, time_t, + const krb5_data *, krb5_data *); /** flags for krb5_parse_name_flags */ enum { @@ -784,7 +795,9 @@ typedef struct krb5_sendto_ctx_data *krb5_sendto_ctx; #define KRB5_SENDTO_RESTART 1 #define KRB5_SENDTO_CONTINUE 2 -typedef krb5_error_code (*krb5_sendto_ctx_func)(krb5_context, krb5_sendto_ctx, void *, const krb5_data *, int *); +typedef krb5_error_code +(KRB5_CALLCONV * krb5_sendto_ctx_func)(krb5_context, krb5_sendto_ctx, void *, + const krb5_data *, int *); struct krb5_plugin; enum krb5_plugin_type { @@ -828,7 +841,7 @@ typedef struct { } krb5_last_req_entry; typedef krb5_error_code -(*krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *); +(KRB5_CALLCONV * krb5_gic_process_last_req)(krb5_context, krb5_last_req_entry **, void *); /* * @@ -854,8 +867,6 @@ 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; extern KRB5_LIB_VARIABLE const char *krb5_cc_type_api; diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index 6acaa2c66b..2fdb76d757 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -274,6 +274,7 @@ typedef struct krb5_context_data { #define KRB5_CTX_F_CHECK_PAC 2 #define KRB5_CTX_F_HOMEDIR_ACCESS 4 #define KRB5_CTX_F_SOCKETS_INITIALIZED 8 +#define KRB5_CTX_F_RD_REQ_IGNORE 16 struct send_to_kdc *send_to_kdc; #ifdef PKINIT hx509_context hx509ctx; diff --git a/source4/heimdal/lib/krb5/krbhst.c b/source4/heimdal/lib/krb5/krbhst.c index ec0c8b738e..d8646f0537 100644 --- a/source4/heimdal/lib/krb5/krbhst.c +++ b/source4/heimdal/lib/krb5/krbhst.c @@ -481,7 +481,7 @@ static krb5_error_code fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, const char *serv_string, int port, int proto) { - char *host; + char *host = NULL; int ret; struct addrinfo *ai; struct addrinfo hints; @@ -500,12 +500,12 @@ fallback_get_hosts(krb5_context context, struct krb5_krbhst_data *kd, } if(kd->fallback_count == 0) - asprintf(&host, "%s.%s.", serv_string, kd->realm); + ret = asprintf(&host, "%s.%s.", serv_string, kd->realm); else - asprintf(&host, "%s-%d.%s.", - serv_string, kd->fallback_count, kd->realm); + ret = asprintf(&host, "%s-%d.%s.", + serv_string, kd->fallback_count, kd->realm); - if (host == NULL) + if (ret < 0 || host == NULL) return ENOMEM; make_hints(&hints, proto); diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index 55c70fc96a..ca0756fdb9 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -165,7 +165,7 @@ struct _heimdal_syslog_data{ int priority; }; -static void +static void KRB5_CALLCONV log_syslog(const char *timestr, const char *msg, void *data) @@ -175,7 +175,7 @@ log_syslog(const char *timestr, syslog(s->priority, "%s", msg); } -static void +static void KRB5_CALLCONV close_syslog(void *data) { free(data); @@ -215,7 +215,7 @@ struct file_data{ int keep_open; }; -static void +static void KRB5_CALLCONV log_file(const char *timestr, const char *msg, void *data) @@ -241,7 +241,7 @@ log_file(const char *timestr, } } -static void +static void KRB5_CALLCONV close_file(void *data) { struct file_data *f = data; @@ -428,8 +428,8 @@ krb5_vlog_msg(krb5_context context, krb5_format_time(context, t, buf, sizeof(buf), TRUE); } if(actual == NULL) { - vasprintf(&msg, fmt, ap); - if(msg == NULL) + int ret = vasprintf(&msg, fmt, ap); + if(ret < 0 || msg == NULL) actual = fmt; else actual = msg; diff --git a/source4/heimdal/lib/krb5/mcache.c b/source4/heimdal/lib/krb5/mcache.c index cdafc67bae..19e6b2345e 100644 --- a/source4/heimdal/lib/krb5/mcache.c +++ b/source4/heimdal/lib/krb5/mcache.c @@ -56,26 +56,27 @@ static struct krb5_mcache *mcc_head; #define MISDEAD(X) ((X)->dead) -static const char* +static const char* KRB5_CALLCONV mcc_get_name(krb5_context context, krb5_ccache id) { return MCACHE(id)->name; } -static krb5_mcache * +static krb5_mcache * KRB5_CALLCONV mcc_alloc(const char *name) { krb5_mcache *m, *m_c; + int ret = 0; ALLOC(m, 1); if(m == NULL) return NULL; if(name == NULL) - asprintf(&m->name, "%p", m); + ret = asprintf(&m->name, "%p", m); else m->name = strdup(name); - if(m->name == NULL) { + if(ret < 0 || m->name == NULL) { free(m); return NULL; } @@ -103,7 +104,7 @@ mcc_alloc(const char *name) return m; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_resolve(krb5_context context, krb5_ccache *id, const char *res) { krb5_mcache *m; @@ -135,7 +136,7 @@ mcc_resolve(krb5_context context, krb5_ccache *id, const char *res) } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_gen_new(krb5_context context, krb5_ccache *id) { krb5_mcache *m; @@ -154,7 +155,7 @@ mcc_gen_new(krb5_context context, krb5_ccache *id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_initialize(krb5_context context, krb5_ccache id, krb5_principal primary_principal) @@ -180,7 +181,7 @@ mcc_close_internal(krb5_mcache *m) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_close(krb5_context context, krb5_ccache id) { @@ -189,7 +190,7 @@ mcc_close(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_destroy(krb5_context context, krb5_ccache id) { @@ -230,7 +231,7 @@ mcc_destroy(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_store_cred(krb5_context context, krb5_ccache id, krb5_creds *creds) @@ -261,7 +262,7 @@ mcc_store_cred(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_principal(krb5_context context, krb5_ccache id, krb5_principal *principal) @@ -275,7 +276,7 @@ mcc_get_principal(krb5_context context, principal); } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_first (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -289,7 +290,7 @@ mcc_get_first (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_next (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor, @@ -311,7 +312,7 @@ mcc_get_next (krb5_context context, return KRB5_CC_END; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_end_get (krb5_context context, krb5_ccache id, krb5_cc_cursor *cursor) @@ -319,7 +320,7 @@ mcc_end_get (krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_remove_cred(krb5_context context, krb5_ccache id, krb5_flags which, @@ -339,7 +340,7 @@ mcc_remove_cred(krb5_context context, return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_set_flags(krb5_context context, krb5_ccache id, krb5_flags flags) @@ -351,7 +352,7 @@ struct mcache_iter { krb5_mcache *cache; }; -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) { struct mcache_iter *iter; @@ -373,7 +374,7 @@ mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) { struct mcache_iter *iter = cursor; @@ -400,7 +401,7 @@ mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) { struct mcache_iter *iter = cursor; @@ -412,7 +413,7 @@ mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to); @@ -447,7 +448,7 @@ mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_default_name(krb5_context context, char **str) { *str = strdup("MEMORY:"); @@ -459,14 +460,14 @@ mcc_default_name(krb5_context context, char **str) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime) { *mtime = MCACHE(id)->mtime; return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset) { krb5_mcache *m = MCACHE(id); @@ -474,7 +475,7 @@ mcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset) return 0; } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV mcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset) { krb5_mcache *m = MCACHE(id); diff --git a/source4/heimdal/lib/krb5/mit_glue.c b/source4/heimdal/lib/krb5/mit_glue.c index 0ff3d7f3c6..7ed91b0768 100644 --- a/source4/heimdal/lib/krb5/mit_glue.c +++ b/source4/heimdal/lib/krb5/mit_glue.c @@ -378,6 +378,12 @@ krb5_c_prf(krb5_context context, return ret; } +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_c_random_make_octets(krb5_context context, krb5_data * data) +{ + return krb5_generate_random_keyblock(context, data->length, data->data); +} + /** * MIT compat glue * @@ -392,4 +398,38 @@ krb5_cc_copy_creds(krb5_context context, return krb5_cc_copy_cache(context, from, to); } +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_auth_con_getsendsubkey(krb5_context context, krb5_auth_context auth_context, + krb5_keyblock **keyblock) +{ + return krb5_auth_con_getlocalsubkey(context, auth_context, keyblock); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_auth_con_getrecvsubkey(krb5_context context, krb5_auth_context auth_context, + krb5_keyblock **keyblock) +{ + return krb5_auth_con_getremotesubkey(context, auth_context, keyblock); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_auth_con_setsendsubkey(krb5_context context, krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setlocalsubkey(context, auth_context, keyblock); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_auth_con_setrecvsubkey(krb5_context context, krb5_auth_context auth_context, + krb5_keyblock *keyblock) +{ + return krb5_auth_con_setremotesubkey(context, auth_context, keyblock); +} + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_free_default_realm(krb5_context context, krb5_realm realm) +{ + return krb5_xfree(realm); +} + #endif /* HEIMDAL_SMALLER */ diff --git a/source4/heimdal/lib/krb5/pcache.c b/source4/heimdal/lib/krb5/pcache.c new file mode 100644 index 0000000000..e7f7a61ec4 --- /dev/null +++ b/source4/heimdal/lib/krb5/pcache.c @@ -0,0 +1,66 @@ +/*********************************************************************** + * Copyright (c) 2010, Secure Endpoints Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - 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. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 + * COPYRIGHT HOLDER 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" +#include "ccache_plugin.h" +#ifdef HAVE_DLFCN_H +#include <dlfcn.h> +#endif +#include <assert.h> + +krb5_error_code +_krb5_load_ccache_plugins(krb5_context context) +{ + struct krb5_plugin * plist = NULL; + struct krb5_plugin *p; + krb5_error_code code; + + code = _krb5_plugin_find(context, PLUGIN_TYPE_DATA, KRB5_PLUGIN_CCACHE, + &plist); + if (code) + return code; + + for (p = plist; p != NULL; p = _krb5_plugin_get_next(p)) { + krb5_cc_ops * ccops; + krb5_error_code c_load; + + ccops = _krb5_plugin_get_symbol(p); + if (ccops != NULL && ccops->version == KRB5_CC_OPS_VERSION) { + c_load = krb5_cc_register(context, ccops, FALSE); + if (c_load != 0) + code = c_load; + } + } + + _krb5_plugin_free(plist); + + return code; +} diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 6711c7702f..92c1200f06 100644 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -1416,10 +1416,7 @@ pk_rd_pa_reply_dh(krb5_context context, } - dh_gen_keylen = DH_size(ctx->u.dh); - size = BN_num_bytes(ctx->u.dh->p); - if (size < dh_gen_keylen) - size = dh_gen_keylen; + size = DH_size(ctx->u.dh); dh_gen_key = malloc(size); if (dh_gen_key == NULL) { @@ -1427,10 +1424,8 @@ pk_rd_pa_reply_dh(krb5_context context, krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); goto out; } - memset(dh_gen_key, 0, size - dh_gen_keylen); - dh_gen_keylen = DH_compute_key(dh_gen_key + (size - dh_gen_keylen), - kdc_dh_pubkey, ctx->u.dh); + dh_gen_keylen = DH_compute_key(dh_gen_key, kdc_dh_pubkey, ctx->u.dh); if (dh_gen_keylen == -1) { ret = KRB5KRB_ERR_GENERIC; dh_gen_keylen = 0; @@ -1438,6 +1433,12 @@ pk_rd_pa_reply_dh(krb5_context context, N_("PKINIT: Can't compute Diffie-Hellman key", "")); goto out; } + if (dh_gen_keylen < size) { + size -= dh_gen_keylen; + memmove(dh_gen_key + size, dh_gen_key, dh_gen_keylen); + memset(dh_gen_key, 0, size); + } + } else { #ifdef HAVE_OPENSSL const EC_GROUP *group; diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index aa71e29b39..e19ba4a27c 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -201,8 +201,19 @@ load_plugins(krb5_context context) dirs = rk_UNCONST(sysplugin_dirs); for (di = dirs; *di != NULL; di++) { +#ifdef KRB5_USE_PATH_TOKENS + { + char * dir = NULL; + if (_krb5_expand_path_tokens(context, *di, &dir)) + continue; + d = opendir(dir); + + free(dir); + } +#else d = opendir(*di); +#endif if (d == NULL) continue; rk_cloexec_dir(d); @@ -215,17 +226,18 @@ load_plugins(krb5_context context) continue; path = NULL; + ret = 0; #ifdef __APPLE__ { /* support loading bundles on MacOS */ size_t len = strlen(n); if (len > 7 && strcmp(&n[len - 7], ".bundle") == 0) - asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n); + ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n); } #endif - if (path == NULL) - asprintf(&path, "%s/%s", *di, n); + if (ret < 0 || path == NULL) + ret = asprintf(&path, "%s/%s", *di, n); - if (path == NULL) { + if (ret < 0 || path == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); return ret; diff --git a/source4/heimdal/lib/krb5/prompter_posix.c b/source4/heimdal/lib/krb5/prompter_posix.c index 875fd99c40..1bf748c512 100644 --- a/source4/heimdal/lib/krb5/prompter_posix.c +++ b/source4/heimdal/lib/krb5/prompter_posix.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -KRB5_LIB_FUNCTION int +KRB5_LIB_FUNCTION int KRB5_CALLCONV krb5_prompter_posix (krb5_context context, void *data, const char *name, diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 6b2ffbdaac..8ce6570de2 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -926,7 +926,7 @@ krb5_rd_req_ctx(krb5_context context, &o->keyblock); if (ret) { /* If caller specified a server, fail. */ - if (service == NULL) + if (service == NULL && (context->flags & KRB5_CTX_F_RD_REQ_IGNORE) == 0) goto out; /* Otherwise, fall back to iterating over the keytab. This * have serious performace issues for larger keytab. diff --git a/source4/heimdal/lib/krb5/replay.c b/source4/heimdal/lib/krb5/replay.c index f4eb9032d7..375a4aaba6 100644 --- a/source4/heimdal/lib/krb5/replay.c +++ b/source4/heimdal/lib/krb5/replay.c @@ -308,12 +308,12 @@ krb5_get_server_rcache(krb5_context context, } strvisx(tmp, piece->data, piece->length, VIS_WHITE | VIS_OCTAL); #ifdef HAVE_GETEUID - asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid()); + ret = asprintf(&name, "FILE:rc_%s_%u", tmp, (unsigned)geteuid()); #else - asprintf(&name, "FILE:rc_%s", tmp); + ret = asprintf(&name, "FILE:rc_%s", tmp); #endif free(tmp); - if(name == NULL) { + if(ret < 0 || name == NULL) { krb5_set_error_message(context, ENOMEM, N_("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 9ff52fa545..2ae8153c8d 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -183,16 +183,16 @@ send_and_recv_http(krb5_socket_t fd, const krb5_data *req, krb5_data *rep) { - char *request; + char *request = NULL; char *str; int ret; int len = base64_encode(req->data, req->length, &str); if(len < 0) return -1; - asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str); + ret = asprintf(&request, "GET %s%s HTTP/1.0\r\n\r\n", prefix, str); free(str); - if (request == NULL) + if (ret < 0 || request == NULL) return -1; ret = net_write (fd, request, strlen(request)); free (request); @@ -261,7 +261,7 @@ send_via_proxy (krb5_context context, { char *proxy2 = strdup(context->http_proxy); char *proxy = proxy2; - char *prefix; + char *prefix = NULL; char *colon; struct addrinfo hints; struct addrinfo *ai, *a; @@ -304,8 +304,8 @@ send_via_proxy (krb5_context context, } freeaddrinfo (ai); - asprintf(&prefix, "http://%s/", hi->hostname); - if(prefix == NULL) { + ret = asprintf(&prefix, "http://%s/", hi->hostname); + if(ret < 0 || prefix == NULL) { close(s); return 1; } @@ -648,7 +648,7 @@ krb5_sendto_context(krb5_context context, return ret; } -krb5_error_code +krb5_error_code KRB5_CALLCONV _krb5_kdc_retry(krb5_context context, krb5_sendto_ctx ctx, void *data, const krb5_data *reply, int *action) { diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index e7d4d9532d..45c97284bf 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -602,7 +602,7 @@ noreferral: } -static krb5_error_code +static krb5_error_code KRB5_CALLCONV decrypt_tkt (krb5_context context, krb5_keyblock *key, krb5_key_usage usage, diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c index 01cf323d37..d47a1288ed 100644 --- a/source4/heimdal/lib/krb5/v4_glue.c +++ b/source4/heimdal/lib/krb5/v4_glue.c @@ -120,7 +120,7 @@ get_krb4_cc_name(const char *tkfile, char **cc) } #ifdef HAVE_GETUID if(*cc == NULL) - if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0) + if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0 || *cc == NULL) return errno; #elif defined(KRB5_USE_PATH_TOKENS) if(*cc == NULL) diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index a4c633936f..63994dfca7 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -46,6 +46,7 @@ _warnerr(krb5_context context, int do_errtext, const char *args[2], **arg; char *msg = NULL; const char *err_str = NULL; + krb5_error_code ret; args[0] = args[1] = NULL; arg = args; @@ -53,8 +54,8 @@ _warnerr(krb5_context context, int do_errtext, strlcat(xfmt, "%s", sizeof(xfmt)); if(do_errtext) strlcat(xfmt, ": ", sizeof(xfmt)); - vasprintf(&msg, fmt, ap); - if(msg == NULL) + ret = vasprintf(&msg, fmt, ap); + if(ret < 0 || msg == NULL) return ENOMEM; *arg++ = msg; } |