From c5bea98ddb2f7967df572160f639da3cba381a87 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 29 Nov 2010 11:24:08 +1100 Subject: s4:heimdal: import lorikeet-heimdal-201012010201 (commit 81fe27bcc0148d410ca4617f8759b9df1a5e935c) --- source4/heimdal/lib/krb5/cache.c | 49 +- source4/heimdal/lib/krb5/changepw.c | 46 +- source4/heimdal/lib/krb5/config_file.c | 73 ++- source4/heimdal/lib/krb5/constants.c | 17 +- source4/heimdal/lib/krb5/context.c | 70 ++- source4/heimdal/lib/krb5/convert_creds.c | 134 +---- source4/heimdal/lib/krb5/creds.c | 2 +- source4/heimdal/lib/krb5/crypto.c | 6 +- source4/heimdal/lib/krb5/error_string.c | 4 +- source4/heimdal/lib/krb5/get_cred.c | 3 +- source4/heimdal/lib/krb5/kcm.c | 4 +- source4/heimdal/lib/krb5/keyblock.c | 2 +- source4/heimdal/lib/krb5/krb5.h | 4 +- source4/heimdal/lib/krb5/krb5_locl.h | 6 +- source4/heimdal/lib/krb5/misc.c | 2 +- source4/heimdal/lib/krb5/pac.c | 62 +- source4/heimdal/lib/krb5/padata.c | 2 +- source4/heimdal/lib/krb5/pcache.c | 2 +- source4/heimdal/lib/krb5/pkinit.c | 16 +- source4/heimdal/lib/krb5/plugin.c | 70 ++- source4/heimdal/lib/krb5/principal.c | 437 +------------- source4/heimdal/lib/krb5/ticket.c | 2 +- source4/heimdal/lib/krb5/v4_glue.c | 960 ------------------------------- source4/heimdal/lib/krb5/warn.c | 8 + 24 files changed, 340 insertions(+), 1641 deletions(-) delete mode 100644 source4/heimdal/lib/krb5/v4_glue.c (limited to 'source4/heimdal/lib/krb5') diff --git a/source4/heimdal/lib/krb5/cache.c b/source4/heimdal/lib/krb5/cache.c index 32a131b07c..211642e568 100644 --- a/source4/heimdal/lib/krb5/cache.c +++ b/source4/heimdal/lib/krb5/cache.c @@ -134,7 +134,7 @@ krb5_cc_register(krb5_context context, } } if(i == context->num_cc_ops) { - const krb5_cc_ops **o = realloc(context->cc_ops, + const krb5_cc_ops **o = realloc(rk_UNCONST(context->cc_ops), (context->num_cc_ops + 1) * sizeof(context->cc_ops[0])); if(o == NULL) { @@ -397,7 +397,7 @@ krb5_cc_get_full_name(krb5_context context, */ -const krb5_cc_ops * +KRB5_LIB_FUNCTION const krb5_cc_ops * KRB5_LIB_CALL krb5_cc_get_ops(krb5_context context, krb5_ccache id) { return id->ops; @@ -461,7 +461,7 @@ environment_changed(krb5_context context) * @ingroup krb5_ccache */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_cc_switch(krb5_context context, krb5_ccache id) { @@ -477,7 +477,7 @@ krb5_cc_switch(krb5_context context, krb5_ccache id) * @ingroup krb5_ccache */ -krb5_boolean KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_cc_support_switch(krb5_context context, const char *type) { const krb5_cc_ops *ops; @@ -512,6 +512,12 @@ krb5_cc_set_default_name(krb5_context context, const char *name) context->default_cc_name_env = strdup(e); } } + +#ifdef _WIN32 + if (e == NULL) { + e = p = _krb5_get_default_cc_name_from_registry(); + } +#endif if (e == NULL) { e = krb5_config_get_string(context, NULL, "libdefaults", "default_cc_name", NULL); @@ -967,7 +973,7 @@ krb5_cc_clear_mcred(krb5_creds *mcred) */ -const krb5_cc_ops * +KRB5_LIB_FUNCTION const krb5_cc_ops * KRB5_LIB_CALL krb5_cc_get_prefix_ops(krb5_context context, const char *prefix) { char *p, *p1; @@ -1183,7 +1189,7 @@ krb5_cc_cache_match (krb5_context context, * @ingroup krb5_ccache */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_cc_move(krb5_context context, krb5_ccache from, krb5_ccache to) { krb5_error_code ret; @@ -1658,7 +1664,7 @@ krb5_cc_get_lifetime(krb5_context context, krb5_ccache id, time_t *t) * @ingroup krb5_ccache */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_cc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat offset) { if (id->ops->set_kdc_offset == NULL) { @@ -1683,7 +1689,7 @@ krb5_cc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat offset) * @ingroup krb5_ccache */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_cc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *offset) { if (id->ops->get_kdc_offset == NULL) { @@ -1692,3 +1698,30 @@ krb5_cc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *offset } return (*id->ops->get_kdc_offset)(context, id, offset); } + + +#ifdef _WIN32 + +char * +_krb5_get_default_cc_name_from_registry() +{ + HKEY hk_k5 = 0; + LONG code; + char * ccname = NULL; + + code = RegOpenKeyEx(HKEY_CURRENT_USER, + "Software\\MIT\\Kerberos5", + 0, KEY_READ, &hk_k5); + + if (code != ERROR_SUCCESS) + return NULL; + + ccname = _krb5_parse_reg_value_as_string(NULL, hk_k5, "ccname", + REG_NONE, 0); + + RegCloseKey(hk_k5); + + return ccname; +} + +#endif diff --git a/source4/heimdal/lib/krb5/changepw.c b/source4/heimdal/lib/krb5/changepw.c index a962f06f5f..22a7c87ef3 100644 --- a/source4/heimdal/lib/krb5/changepw.c +++ b/source4/heimdal/lib/krb5/changepw.c @@ -72,7 +72,7 @@ chgpw_send_request (krb5_context context, krb5_creds *creds, krb5_principal targprinc, int is_stream, - int sock, + rk_socket_t sock, const char *passwd, const char *host) { @@ -141,8 +141,8 @@ chgpw_send_request (krb5_context context, iov[2].iov_base = krb_priv_data.data; iov[2].iov_len = krb_priv_data.length; - if (sendmsg (sock, &msghdr, 0) < 0) { - ret = errno; + if (rk_IS_SOCKET_ERROR( sendmsg (sock, &msghdr, 0) )) { + ret = rk_SOCK_ERRNO; krb5_set_error_message(context, ret, "sendmsg %s: %s", host, strerror(ret)); } @@ -164,7 +164,7 @@ setpw_send_request (krb5_context context, krb5_creds *creds, krb5_principal targprinc, int is_stream, - int sock, + rk_socket_t sock, const char *passwd, const char *host) { @@ -251,8 +251,8 @@ setpw_send_request (krb5_context context, iov[2].iov_base = krb_priv_data.data; iov[2].iov_len = krb_priv_data.length; - if (sendmsg (sock, &msghdr, 0) < 0) { - ret = errno; + if (rk_IS_SOCKET_ERROR( sendmsg (sock, &msghdr, 0) )) { + ret = rk_SOCK_ERRNO; krb5_set_error_message(context, ret, "sendmsg %s: %s", host, strerror(ret)); } @@ -268,7 +268,7 @@ static krb5_error_code process_reply (krb5_context context, krb5_auth_context auth_context, int is_stream, - int sock, + rk_socket_t sock, int *result_code, krb5_data *result_code_string, krb5_data *result_string, @@ -288,8 +288,8 @@ process_reply (krb5_context context, ret = recvfrom (sock, reply + len, sizeof(reply) - len, 0, NULL, NULL); - if (ret < 0) { - save_errno = errno; + if (rk_IS_SOCKET_ERROR(ret)) { + save_errno = rk_SOCK_ERRNO; krb5_set_error_message(context, save_errno, "recvfrom %s: %s", host, strerror(save_errno)); @@ -316,8 +316,8 @@ process_reply (krb5_context context, } } else { ret = recvfrom (sock, reply, sizeof(reply), 0, NULL, NULL); - if (ret < 0) { - save_errno = errno; + if (rk_IS_SOCKET_ERROR(ret)) { + save_errno = rk_SOCK_ERRNO; krb5_set_error_message(context, save_errno, "recvfrom %s: %s", host, strerror(save_errno)); @@ -464,13 +464,13 @@ typedef krb5_error_code (*kpwd_send_request) (krb5_context, krb5_creds *, krb5_principal, int, - int, + rk_socket_t, const char *, const char *); typedef krb5_error_code (*kpwd_process_reply) (krb5_context, krb5_auth_context, int, - int, + rk_socket_t, int *, krb5_data *, krb5_data *, @@ -517,7 +517,7 @@ change_password_loop (krb5_context context, krb5_auth_context auth_context = NULL; krb5_krbhst_handle handle = NULL; krb5_krbhst_info *hi; - int sock; + rk_socket_t sock; unsigned int i; int done = 0; krb5_realm realm; @@ -565,20 +565,20 @@ change_password_loop (krb5_context context, int replied = 0; sock = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol); - if (sock < 0) + if (rk_IS_BAD_SOCKET(sock)) continue; rk_cloexec(sock); ret = connect(sock, a->ai_addr, a->ai_addrlen); - if (ret < 0) { - close (sock); + if (rk_IS_SOCKET_ERROR(ret)) { + rk_closesocket (sock); goto out; } ret = krb5_auth_con_genaddrs (context, auth_context, sock, KRB5_AUTH_CONTEXT_GENERATE_LOCAL_ADDR); if (ret) { - close (sock); + rk_closesocket (sock); goto out; } @@ -598,7 +598,7 @@ change_password_loop (krb5_context context, newpw, hi->hostname); if (ret) { - close(sock); + rk_closesocket(sock); goto out; } } @@ -608,7 +608,7 @@ change_password_loop (krb5_context context, ret = ERANGE; krb5_set_error_message(context, ret, "fd %d too large", sock); - close (sock); + rk_closesocket (sock); goto out; } #endif @@ -619,8 +619,8 @@ change_password_loop (krb5_context context, tv.tv_sec = 1 + (1 << i); ret = select (sock + 1, &fdset, NULL, NULL, &tv); - if (ret < 0 && errno != EINTR) { - close(sock); + if (rk_IS_SOCKET_ERROR(ret) && rk_SOCK_ERRNO != EINTR) { + rk_closesocket(sock); goto out; } if (ret == 1) { @@ -640,7 +640,7 @@ change_password_loop (krb5_context context, ret = KRB5_KDC_UNREACH; } } - close (sock); + rk_closesocket (sock); } } diff --git a/source4/heimdal/lib/krb5/config_file.c b/source4/heimdal/lib/krb5/config_file.c index 5840b8d9bd..d08c5b5851 100644 --- a/source4/heimdal/lib/krb5/config_file.c +++ b/source4/heimdal/lib/krb5/config_file.c @@ -84,8 +84,8 @@ static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent, const char **err_message); -static krb5_config_section * -get_entry(krb5_config_section **parent, const char *name, int type) +krb5_config_section * +_krb5_config_get_entry(krb5_config_section **parent, const char *name, int type) { krb5_config_section **q; @@ -135,7 +135,7 @@ parse_section(char *p, krb5_config_section **s, krb5_config_section **parent, return KRB5_CONFIG_BADFORMAT; } *p1 = '\0'; - tmp = get_entry(parent, p + 1, krb5_config_list); + tmp = _krb5_config_get_entry(parent, p + 1, krb5_config_list); if(tmp == NULL) { *err_message = "out of memory"; return KRB5_CONFIG_BADFORMAT; @@ -154,7 +154,7 @@ static krb5_error_code parse_list(struct fileptr *f, unsigned *lineno, krb5_config_binding **parent, const char **err_message) { - char buf[BUFSIZ]; + char buf[KRB5_BUFSIZ]; krb5_error_code ret; krb5_config_binding *b = NULL; unsigned beg_lineno = *lineno; @@ -216,14 +216,14 @@ parse_binding(struct fileptr *f, unsigned *lineno, char *p, ++p; *p2 = '\0'; if (*p == '{') { - tmp = get_entry(parent, p1, krb5_config_list); + tmp = _krb5_config_get_entry(parent, p1, krb5_config_list); if (tmp == NULL) { *err_message = "out of memory"; return KRB5_CONFIG_BADFORMAT; } ret = parse_list (f, lineno, &tmp->u.list, err_message); } else { - tmp = get_entry(parent, p1, krb5_config_string); + tmp = _krb5_config_get_entry(parent, p1, krb5_config_string); if (tmp == NULL) { *err_message = "out of memory"; return KRB5_CONFIG_BADFORMAT; @@ -282,10 +282,10 @@ convert_content(const void *key, const void *value, void *context) return; if (CFGetTypeID(value) == CFStringGetTypeID()) { - tmp = get_entry(parent, k, krb5_config_string); + tmp = _krb5_config_get_entry(parent, k, krb5_config_string); tmp->u.string = cfstring2cstring(value); } else if (CFGetTypeID(value) == CFDictionaryGetTypeID()) { - tmp = get_entry(parent, k, krb5_config_list); + tmp = _krb5_config_get_entry(parent, k, krb5_config_list); CFDictionaryApplyFunction(value, convert_content, &tmp->u.list); } else { /* log */ @@ -352,7 +352,7 @@ krb5_config_parse_debug (struct fileptr *f, { krb5_config_section *s = NULL; krb5_config_binding *b = NULL; - char buf[BUFSIZ]; + char buf[KRB5_BUFSIZ]; krb5_error_code ret; while (config_fgets(buf, sizeof(buf), f) != NULL) { @@ -864,6 +864,55 @@ krb5_config_get_string_default (krb5_context context, return ret; } +static char * +next_component_string(char * begin, char * delims, char **state) +{ + char * end; + + if (begin == NULL) + begin = *state; + + if (*begin == '\0') + return NULL; + + end = begin; + while (*end == '"') { + char * t; + while ((t = strchr(end + 1, '"')) != NULL && *(t - 1) == '\\') { + --t; + memmove(t, t + 1, strlen(t)); + end = t; + } + + if (t) + end = ++t; + else + end += strlen(end); + } + + if (*end != '\0') { + size_t pos; + + pos = strcspn(end, delims); + end = end + pos; + } + + if (*end != '\0') { + *end = '\0'; + *state = end + 1; + if (*begin == '"' && *(end - 1) == '"' && begin + 1 < end) { + begin++; *(end - 1) = '\0'; + } + return begin; + } + + *state = end; + if (*begin == '"' && *(end - 1) == '"' && begin + 1 < end) { + begin++; *(end - 1) = '\0'; + } + return begin; +} + /** * Get a list of configuration strings, free the result with * krb5_config_free_strings(). @@ -894,7 +943,7 @@ krb5_config_vget_strings(krb5_context context, char *s; if(tmp == NULL) goto cleanup; - s = strtok_r(tmp, " \t", &pos); + s = next_component_string(tmp, " \t", &pos); while(s){ char **tmp2 = realloc(strings, (nstr + 1) * sizeof(*strings)); if(tmp2 == NULL) @@ -904,7 +953,7 @@ krb5_config_vget_strings(krb5_context context, nstr++; if(strings[nstr-1] == NULL) goto cleanup; - s = strtok_r(NULL, " \t", &pos); + s = next_component_string(NULL, " \t", &pos); } free(tmp); } @@ -1259,7 +1308,7 @@ krb5_config_get_int (krb5_context context, */ KRB5_DEPRECATED -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_config_parse_string_multi(krb5_context context, const char *string, krb5_config_section **res) diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index 6223fb5d6b..bbb4832657 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -37,15 +37,18 @@ KRB5_LIB_VARIABLE const char *krb5_config_file = #ifdef __APPLE__ -"~/Library/Preferences/com.apple.Kerberos.plist:" -"/Library/Preferences/com.apple.Kerberos.plist:" -"~/Library/Preferences/edu.mit.Kerberos:" -"/Library/Preferences/edu.mit.Kerberos:" +"~/Library/Preferences/com.apple.Kerberos.plist" PATH_SEP +"/Library/Preferences/com.apple.Kerberos.plist" PATH_SEP +"~/Library/Preferences/edu.mit.Kerberos" PATH_SEP +"/Library/Preferences/edu.mit.Kerberos" PATH_SEP #endif /* __APPLE__ */ -"~/.krb5/config:" +"~/.krb5/config" PATH_SEP SYSCONFDIR "/krb5.conf" -#ifndef _WIN32 -":/etc/krb5.conf" +#ifdef _WIN32 +PATH_SEP "%{COMMON_APPDATA}/Kerberos/krb5.conf" +PATH_SEP "%{WINDOWS}/krb5.ini" +#else +PATH_SEP "/etc/krb5.conf" #endif ; diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index 100eb1237d..d4e48d26c7 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -269,7 +269,7 @@ cc_ops_copy(krb5_context context, const krb5_context src_context) return KRB5_CC_NOMEM; } - memcpy(cc_ops, src_context->cc_ops, + memcpy(rk_UNCONST(cc_ops), src_context->cc_ops, sizeof(cc_ops[0]) * src_context->num_cc_ops); context->cc_ops = cc_ops; context->num_cc_ops = src_context->num_cc_ops; @@ -559,7 +559,7 @@ krb5_free_context(krb5_context context) krb5_free_host_realm (context, context->default_realms); krb5_config_file_free (context, context->cf); free_error_table (context->et_list); - free(context->cc_ops); + free(rk_UNCONST(context->cc_ops)); free(context->kt_types); krb5_clear_error_message(context); if(context->warn_dest != NULL) @@ -616,6 +616,11 @@ krb5_set_config_files(krb5_context context, char **filenames) if(tmp == NULL) return ENXIO; #endif + +#ifdef _WIN32 + _krb5_load_config_from_registry(context, &tmp); +#endif + krb5_config_file_free(context, context->cf); context->cf = tmp; ret = init_context_from_config_file(context); @@ -668,7 +673,7 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp) while(1) { ssize_t l; q = p; - l = strsep_copy(&q, ":", NULL, 0); + l = strsep_copy(&q, PATH_SEP, NULL, 0); if(l == -1) break; fn = malloc(l + 1); @@ -676,7 +681,7 @@ krb5_prepend_config_files(const char *filelist, char **pq, char ***ret_pp) krb5_free_config_files(pp); return ENOMEM; } - (void)strsep_copy(&p, ":", fn, l + 1); + (void)strsep_copy(&p, PATH_SEP, fn, l + 1); ret = add_file(&pp, &len, fn); if (ret) { krb5_free_config_files(pp); @@ -736,6 +741,45 @@ krb5_prepend_config_files_default(const char *filelist, char ***pfilenames) return 0; } +#ifdef _WIN32 + +/** + * Checks the registry for configuration file location + * + * Kerberos for Windows and other legacy Kerberos applications expect + * to find the configuration file location in the + * SOFTWARE\MIT\Kerberos registry key under the value "config". + */ +char * +_krb5_get_default_config_config_files_from_registry() +{ + static const char * KeyName = "Software\\MIT\\Kerberos"; + char *config_file = NULL; + LONG rcode; + HKEY key; + + rcode = RegOpenKeyEx(HKEY_CURRENT_USER, KeyName, 0, KEY_READ, &key); + if (rcode == ERROR_SUCCESS) { + config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config", + REG_NONE, 0, PATH_SEP); + RegCloseKey(key); + } + + if (config_file) + return config_file; + + rcode = RegOpenKeyEx(HKEY_LOCAL_MACHINE, KeyName, 0, KEY_READ, &key); + if (rcode == ERROR_SUCCESS) { + config_file = _krb5_parse_reg_value_as_multi_string(NULL, key, "config", + REG_NONE, 0, PATH_SEP); + RegCloseKey(key); + } + + return config_file; +} + +#endif + /** * Get the global configuration list. * @@ -756,6 +800,22 @@ krb5_get_default_config_files(char ***pfilenames) return EINVAL; if(!issuid()) files = getenv("KRB5_CONFIG"); + +#ifdef _WIN32 + if (files == NULL) { + char * reg_files; + reg_files = _krb5_get_default_config_config_files_from_registry(); + if (reg_files != NULL) { + krb5_error_code code; + + code = krb5_prepend_config_files(reg_files, NULL, pfilenames); + free(reg_files); + + return code; + } + } +#endif + if (files == NULL) files = krb5_config_file; @@ -1425,7 +1485,7 @@ _krb5_homedir_access(krb5_context context) * @ingroup krb5 */ -krb5_boolean +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_set_home_dir_access(krb5_context context, krb5_boolean allow) { krb5_boolean old; diff --git a/source4/heimdal/lib/krb5/convert_creds.c b/source4/heimdal/lib/krb5/convert_creds.c index aff843e785..e700425ffe 100644 --- a/source4/heimdal/lib/krb5/convert_creds.c +++ b/source4/heimdal/lib/krb5/convert_creds.c @@ -31,17 +31,13 @@ * SUCH DAMAGE. */ +#define KRB5_DEPRECATED + #include "krb5_locl.h" #include "krb5-v4compat.h" #ifndef HEIMDAL_SMALLER -static krb5_error_code -check_ticket_flags(TicketFlags f) -{ - return 0; /* maybe add some more tests here? */ -} - /** * Convert the v5 credentials in in_cred to v4-dito in v4creds. This * is done by sending them to the 524 function in the KDC. If @@ -58,91 +54,16 @@ check_ticket_flags(TicketFlags f) * @ingroup krb5_v4compat */ +KRB5_DEPRECATED KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb524_convert_creds_kdc(krb5_context context, krb5_creds *in_cred, struct credentials *v4creds) { - krb5_error_code ret; - krb5_data reply; - krb5_storage *sp; - int32_t tmp; - krb5_data ticket; - char realm[REALM_SZ]; - krb5_creds *v5_creds = in_cred; - - ret = check_ticket_flags(v5_creds->flags.b); - if(ret) - goto out2; - - { - krb5_krbhst_handle handle; - - ret = krb5_krbhst_init(context, - krb5_principal_get_realm(context, - v5_creds->server), - KRB5_KRBHST_KRB524, - &handle); - if (ret) - goto out2; - - ret = krb5_sendto (context, - &v5_creds->ticket, - handle, - &reply); - krb5_krbhst_free(context, handle); - if (ret) - goto out2; - } - sp = krb5_storage_from_mem(reply.data, reply.length); - if(sp == NULL) { - ret = ENOMEM; - krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", "")); - goto out2; - } - krb5_ret_int32(sp, &tmp); - ret = tmp; - if(ret == 0) { - memset(v4creds, 0, sizeof(*v4creds)); - ret = krb5_ret_int32(sp, &tmp); - if(ret) - goto out; - v4creds->kvno = tmp; - ret = krb5_ret_data(sp, &ticket); - if(ret) - goto out; - v4creds->ticket_st.length = ticket.length; - memcpy(v4creds->ticket_st.dat, ticket.data, ticket.length); - krb5_data_free(&ticket); - ret = krb5_524_conv_principal(context, - v5_creds->server, - v4creds->service, - v4creds->instance, - v4creds->realm); - if(ret) - goto out; - v4creds->issue_date = v5_creds->times.starttime; - v4creds->lifetime = _krb5_krb_time_to_life(v4creds->issue_date, - v5_creds->times.endtime); - ret = krb5_524_conv_principal(context, v5_creds->client, - v4creds->pname, - v4creds->pinst, - realm); - if(ret) - goto out; - memcpy(v4creds->session, v5_creds->session.keyvalue.data, 8); - } else { - krb5_prepend_error_message(context, ret, - N_("converting credentials", - "already localized")); - } -out: - krb5_storage_free(sp); - krb5_data_free(&reply); -out2: - if (v5_creds != in_cred) - krb5_free_creds (context, v5_creds); - return ret; + memset(v4creds, 0, sizeof(*v4creds)); + krb5_set_error_message(context, EINVAL, + N_("krb524_convert_creds_kdc not supported", "")); + return EINVAL; } /** @@ -160,48 +81,17 @@ out2: * @ingroup krb5_v4compat */ +KRB5_DEPRECATED KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb524_convert_creds_kdc_ccache(krb5_context context, krb5_ccache ccache, krb5_creds *in_cred, struct credentials *v4creds) { - krb5_error_code ret; - krb5_creds *v5_creds = in_cred; - krb5_keytype keytype; - - keytype = v5_creds->session.keytype; - - if (keytype != ENCTYPE_DES_CBC_CRC) { - /* MIT krb524d doesn't like nothing but des-cbc-crc tickets, - so go get one */ - krb5_creds template; - - memset (&template, 0, sizeof(template)); - template.session.keytype = ENCTYPE_DES_CBC_CRC; - ret = krb5_copy_principal (context, in_cred->client, &template.client); - if (ret) { - krb5_free_cred_contents (context, &template); - return ret; - } - ret = krb5_copy_principal (context, in_cred->server, &template.server); - if (ret) { - krb5_free_cred_contents (context, &template); - return ret; - } - - ret = krb5_get_credentials (context, 0, ccache, - &template, &v5_creds); - krb5_free_cred_contents (context, &template); - if (ret) - return ret; - } - - ret = krb524_convert_creds_kdc(context, v5_creds, v4creds); - - if (v5_creds != in_cred) - krb5_free_creds (context, v5_creds); - return ret; + memset(v4creds, 0, sizeof(*v4creds)); + krb5_set_error_message(context, EINVAL, + N_("krb524_convert_creds_kdc_ccache not supported", "")); + return EINVAL; } #endif diff --git a/source4/heimdal/lib/krb5/creds.c b/source4/heimdal/lib/krb5/creds.c index fd277148d5..69aacdc032 100644 --- a/source4/heimdal/lib/krb5/creds.c +++ b/source4/heimdal/lib/krb5/creds.c @@ -278,7 +278,7 @@ krb5_compare_creds(krb5_context context, krb5_flags whichfields, * @ingroup krb5 */ -unsigned long +KRB5_LIB_FUNCTION unsigned long KRB5_LIB_CALL krb5_creds_get_ticket_flags(krb5_creds *creds) { return TicketFlags2int(creds->flags.b); diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index f0b0692bc0..aa417e15eb 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -476,7 +476,7 @@ verify_checksum(krb5_context context, krb5_set_error_message(context, ret, N_("Decrypt integrity check failed for checksum " "type %s, key type %s", ""), - ct->name, crypto->et->name); + ct->name, (crypto != NULL)? crypto->et->name : "(none)"); return ret; } @@ -2315,7 +2315,7 @@ wrapped_length_dervied (krb5_context context, * Return the size of an encrypted packet of length `data_len' */ -size_t +KRB5_LIB_FUNCTION size_t KRB5_LIB_CALL krb5_get_wrapped_length (krb5_context context, krb5_crypto crypto, size_t data_len) @@ -2361,7 +2361,7 @@ crypto_overhead_dervied (krb5_context context, return res; } -size_t +KRB5_LIB_FUNCTION size_t KRB5_LIB_CALL krb5_crypto_overhead (krb5_context context, krb5_crypto crypto) { if (derived_crypto (context, crypto)) diff --git a/source4/heimdal/lib/krb5/error_string.c b/source4/heimdal/lib/krb5/error_string.c index 237d346f4d..dc2d4586a0 100644 --- a/source4/heimdal/lib/krb5/error_string.c +++ b/source4/heimdal/lib/krb5/error_string.c @@ -122,7 +122,7 @@ krb5_vset_error_message (krb5_context context, krb5_error_code ret, * @ingroup krb5_error */ -void KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_prepend_error_message(krb5_context context, krb5_error_code ret, const char *fmt, ...) __attribute__ ((format (printf, 3, 4))) @@ -145,7 +145,7 @@ krb5_prepend_error_message(krb5_context context, krb5_error_code ret, * @ingroup krb5_error */ -void KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_vprepend_error_message(krb5_context context, krb5_error_code ret, const char *fmt, va_list args) __attribute__ ((format (printf, 3, 0))) diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 901182192d..e06d4a12be 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -768,7 +768,8 @@ get_cred_kdc_capath_worker(krb5_context context, ret = find_cred(context, ccache, tmp_creds.server, *ret_tgts, &tgts); if(ret == 0){ - if (strcmp(try_realm, client_realm) != 0) + /* only allow implicit ok_as_delegate if the realm is the clients realm */ + if (strcmp(try_realm, client_realm) != 0 || strcmp(try_realm, server_realm) != 0) ok_as_delegate = tgts.flags.b.ok_as_delegate; *out_creds = calloc(1, sizeof(**out_creds)); diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index 80a72ecbf7..1fe15d8064 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -97,7 +97,7 @@ kcm_send_request(krb5_context context, return ret; } -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_kcm_storage_request(krb5_context context, uint16_t opcode, krb5_storage **storage_p) @@ -164,7 +164,7 @@ kcm_alloc(krb5_context context, const char *name, krb5_ccache *id) return 0; } -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_kcm_call(krb5_context context, krb5_storage *request, krb5_storage **response_p, diff --git a/source4/heimdal/lib/krb5/keyblock.c b/source4/heimdal/lib/krb5/keyblock.c index 2d57e301d5..f34a5c4f90 100644 --- a/source4/heimdal/lib/krb5/keyblock.c +++ b/source4/heimdal/lib/krb5/keyblock.c @@ -155,7 +155,7 @@ krb5_copy_keyblock (krb5_context context, * @ingroup krb5_crypto */ -krb5_enctype +KRB5_LIB_FUNCTION krb5_enctype KRB5_LIB_CALL krb5_keyblock_get_enctype(const krb5_keyblock *block) { return block->keytype; diff --git a/source4/heimdal/lib/krb5/krb5.h b/source4/heimdal/lib/krb5/krb5.h index 8f4210e19b..dd579f973b 100644 --- a/source4/heimdal/lib/krb5/krb5.h +++ b/source4/heimdal/lib/krb5/krb5.h @@ -80,7 +80,7 @@ typedef int krb5_boolean; typedef int32_t krb5_error_code; -typedef int krb5_kvno; +typedef int32_t krb5_kvno; typedef uint32_t krb5_flags; @@ -847,6 +847,8 @@ typedef krb5_error_code * */ +struct hx509_certs_data; + #include /* variables */ diff --git a/source4/heimdal/lib/krb5/krb5_locl.h b/source4/heimdal/lib/krb5/krb5_locl.h index d8d038e7bb..bdd725e9ea 100644 --- a/source4/heimdal/lib/krb5/krb5_locl.h +++ b/source4/heimdal/lib/krb5/krb5_locl.h @@ -188,6 +188,10 @@ struct _krb5_krb_auth_data; #define ALLOC(X, N) (X) = calloc((N), sizeof(*(X))) #define ALLOC_SEQ(X, N) do { (X)->len = (N); ALLOC((X)->val, (N)); } while(0) +#ifndef PATH_SEP +#define PATH_SEP ":" +#endif + /* should this be public? */ #define KEYTAB_DEFAULT "FILE:" SYSCONFDIR "/krb5.keytab" #define KEYTAB_DEFAULT_MODIFY "FILE:" SYSCONFDIR "/krb5.keytab" @@ -208,7 +212,7 @@ struct _krb5_krb_auth_data; #endif -#define KRB5_BUFSIZ 1024 +#define KRB5_BUFSIZ 2048 typedef enum { KRB5_INIT_CREDS_TRISTATE_UNSET = 0, diff --git a/source4/heimdal/lib/krb5/misc.c b/source4/heimdal/lib/krb5/misc.c index 733d20f174..f90624cfca 100644 --- a/source4/heimdal/lib/krb5/misc.c +++ b/source4/heimdal/lib/krb5/misc.c @@ -84,7 +84,7 @@ out: } krb5_error_code -_krb5_enomem(krb5_context context) +krb5_enomem(krb5_context context) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; diff --git a/source4/heimdal/lib/krb5/pac.c b/source4/heimdal/lib/krb5/pac.c index d50052c8bc..db2428f95b 100644 --- a/source4/heimdal/lib/krb5/pac.c +++ b/source4/heimdal/lib/krb5/pac.c @@ -116,7 +116,7 @@ HMAC_MD5_any_checksum(krb5_context context, * */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_parse(krb5_context context, const void *ptr, size_t len, krb5_pac *pac) { @@ -127,13 +127,13 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, p = calloc(1, sizeof(*p)); if (p == NULL) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } sp = krb5_storage_from_readonly_mem(ptr, len); if (sp == NULL) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -156,7 +156,7 @@ krb5_pac_parse(krb5_context context, const void *ptr, size_t len, p->pac = calloc(1, sizeof(*p->pac) + (sizeof(p->pac->buffers[0]) * (tmp - 1))); if (p->pac == NULL) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } @@ -258,7 +258,7 @@ out: return ret; } -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_init(krb5_context context, krb5_pac *pac) { krb5_error_code ret; @@ -266,27 +266,27 @@ krb5_pac_init(krb5_context context, krb5_pac *pac) p = calloc(1, sizeof(*p)); if (p == NULL) { - return _krb5_enomem(context); + return krb5_enomem(context); } p->pac = calloc(1, sizeof(*p->pac)); if (p->pac == NULL) { free(p); - return _krb5_enomem(context); + return krb5_enomem(context); } ret = krb5_data_alloc(&p->data, PACTYPE_SIZE); if (ret) { free (p->pac); free(p); - return _krb5_enomem(context); + return krb5_enomem(context); } *pac = p; return 0; } -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_add_buffer(krb5_context context, krb5_pac p, uint32_t type, const krb5_data *data) { @@ -300,7 +300,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) - return _krb5_enomem(context); + return krb5_enomem(context); p->pac = ptr; @@ -367,7 +367,7 @@ krb5_pac_add_buffer(krb5_context context, krb5_pac p, * @ingroup krb5_pac */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_get_buffer(krb5_context context, krb5_pac p, uint32_t type, krb5_data *data) { @@ -397,7 +397,7 @@ krb5_pac_get_buffer(krb5_context context, krb5_pac p, * */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_get_types(krb5_context context, krb5_pac p, size_t *len, @@ -408,7 +408,7 @@ krb5_pac_get_types(krb5_context context, *types = calloc(p->pac->numbuffers, sizeof(*types)); if (*types == NULL) { *len = 0; - return _krb5_enomem(context); + return krb5_enomem(context); } for (i = 0; i < p->pac->numbuffers; i++) (*types)[i] = p->pac->buffers[i].type; @@ -421,7 +421,7 @@ krb5_pac_get_types(krb5_context context, * */ -void +KRB5_LIB_FUNCTION void KRB5_LIB_CALL krb5_pac_free(krb5_context context, krb5_pac pac) { krb5_data_free(&pac->data); @@ -450,7 +450,7 @@ verify_checksum(krb5_context context, sp = krb5_storage_from_mem((char *)data->data + sig->offset_lo, sig->buffersize); if (sp == NULL) - return _krb5_enomem(context); + return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -460,7 +460,7 @@ 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) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } ret = krb5_storage_read(sp, cksum.checksum.data, cksum.checksum.length); @@ -604,7 +604,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) - return _krb5_enomem(context); + return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -631,7 +631,7 @@ verify_logonname(krb5_context context, s = malloc(len); if (s == NULL) { krb5_storage_free(sp); - return _krb5_enomem(context); + return krb5_enomem(context); } ret = krb5_storage_read(sp, s, len); if (ret != len) { @@ -648,7 +648,7 @@ verify_logonname(krb5_context context, ucs2 = malloc(sizeof(ucs2[0]) * ucs2len); if (ucs2 == NULL) - return _krb5_enomem(context); + return krb5_enomem(context); ret = wind_ucs2read(s, len, &flags, ucs2, &ucs2len); free(s); @@ -667,7 +667,7 @@ verify_logonname(krb5_context context, s = malloc(u8len); if (s == NULL) { free(ucs2); - return _krb5_enomem(context); + return krb5_enomem(context); } ret = wind_ucs2utf8(ucs2, ucs2len, s, &u8len); free(ucs2); @@ -714,7 +714,7 @@ build_logon_name(krb5_context context, sp = krb5_storage_emem(); if (sp == NULL) - return _krb5_enomem(context); + return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); @@ -733,7 +733,7 @@ build_logon_name(krb5_context context, #if 1 /* cheat for now */ s2 = malloc(len * 2); if (s2 == NULL) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); free(s); goto out; } @@ -749,7 +749,7 @@ build_logon_name(krb5_context context, ret = krb5_storage_write(sp, s2, len * 2); free(s2); if (ret != len * 2) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } ret = krb5_storage_to_data(sp, logon); @@ -780,7 +780,7 @@ out: * @ingroup krb5_pac */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_pac_verify(krb5_context context, const krb5_pac pac, time_t authtime, @@ -877,7 +877,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) - return _krb5_enomem(context); + return krb5_enomem(context); len -= sret; } @@ -949,7 +949,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) - return _krb5_enomem(context); + return krb5_enomem(context); p->pac = ptr; @@ -986,14 +986,14 @@ _krb5_pac_sign(krb5_context context, /* Encode PAC */ sp = krb5_storage_emem(); if (sp == NULL) - return _krb5_enomem(context); + return krb5_enomem(context); krb5_storage_set_flags(sp, KRB5_STORAGE_BYTEORDER_LE); spdata = krb5_storage_emem(); if (spdata == NULL) { krb5_storage_free(sp); - return _krb5_enomem(context); + return krb5_enomem(context); } krb5_storage_set_flags(spdata, KRB5_STORAGE_BYTEORDER_LE); @@ -1031,7 +1031,7 @@ _krb5_pac_sign(krb5_context context, sret = krb5_storage_write(spdata, ptr, len); if (sret != len) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } /* XXX if not aligned, fill_zeros */ @@ -1068,14 +1068,14 @@ _krb5_pac_sign(krb5_context context, ret = krb5_storage_write(sp, d.data, d.length); if (ret != d.length) { krb5_data_free(&d); - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } krb5_data_free(&d); ret = krb5_storage_to_data(sp, &d); if (ret) { - ret = _krb5_enomem(context); + ret = krb5_enomem(context); goto out; } diff --git a/source4/heimdal/lib/krb5/padata.c b/source4/heimdal/lib/krb5/padata.c index 283a857df5..98420a7332 100644 --- a/source4/heimdal/lib/krb5/padata.c +++ b/source4/heimdal/lib/krb5/padata.c @@ -33,7 +33,7 @@ #include "krb5_locl.h" -PA_DATA * +KRB5_LIB_FUNCTION PA_DATA * KRB5_LIB_CALL krb5_find_padata(PA_DATA *val, unsigned len, int type, int *idx) { for(; *idx < len; (*idx)++) diff --git a/source4/heimdal/lib/krb5/pcache.c b/source4/heimdal/lib/krb5/pcache.c index e7f7a61ec4..23d5389a60 100644 --- a/source4/heimdal/lib/krb5/pcache.c +++ b/source4/heimdal/lib/krb5/pcache.c @@ -54,7 +54,7 @@ _krb5_load_ccache_plugins(krb5_context context) ccops = _krb5_plugin_get_symbol(p); if (ccops != NULL && ccops->version == KRB5_CC_OPS_VERSION) { - c_load = krb5_cc_register(context, ccops, FALSE); + c_load = krb5_cc_register(context, ccops, TRUE); if (c_load != 0) code = c_load; } diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 92c1200f06..1bf922baf6 100644 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -2455,9 +2455,9 @@ krb5_get_init_creds_opt_set_pkinit(krb5_context context, } krb5_error_code KRB5_LIB_FUNCTION -_krb5_get_init_creds_opt_set_pkinit_user_certs(krb5_context context, - krb5_get_init_creds_opt *opt, - struct hx509_certs_data *certs) +krb5_get_init_creds_opt_set_pkinit_user_certs(krb5_context context, + krb5_get_init_creds_opt *opt, + struct hx509_certs_data *certs) { #ifdef PKINIT if (opt->opt_private == NULL) { @@ -2529,11 +2529,11 @@ find_ms_san(hx509_context context, hx509_cert cert, void *ctx) */ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_pk_enterprise_cert(krb5_context context, - const char *user_id, - krb5_const_realm realm, - krb5_principal *principal, - struct hx509_certs_data **res) +krb5_pk_enterprise_cert(krb5_context context, + const char *user_id, + krb5_const_realm realm, + krb5_principal *principal, + struct hx509_certs_data **res) { #ifdef PKINIT krb5_error_code ret; diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index 89be46c1ae..8aff72ec85 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -135,7 +135,7 @@ loadlib(krb5_context context, char *path) * @ingroup krb5_support */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_plugin_register(krb5_context context, enum krb5_plugin_type type, const char *name, @@ -179,6 +179,43 @@ krb5_plugin_register(krb5_context context, return 0; } +static int +is_valid_plugin_filename(const char * n) +{ + if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0'))) + return 0; + +#ifdef _WIN32 + /* On Windows, we only attempt to load .dll files as plug-ins. */ + { + const char * ext; + + ext = strrchr(n, '.'); + if (ext == NULL) + return 0; + + return !stricmp(ext, ".dll"); + } +#endif + + return 1; +} + +static void +trim_trailing_slash(char * path) +{ + size_t l; + + l = strlen(path); + while (l > 0 && (path[l - 1] == '/' +#ifdef BACKSLASH_PATH_DELIM + || path[l - 1] == '\\' +#endif + )) { + path[--l] = '\0'; + } +} + static krb5_error_code load_plugins(krb5_context context) { @@ -201,28 +238,27 @@ load_plugins(krb5_context context) dirs = rk_UNCONST(sysplugin_dirs); for (di = dirs; *di != NULL; di++) { + char * dir = *di; + #ifdef KRB5_USE_PATH_TOKENS - { - char * dir = NULL; + if (_krb5_expand_path_tokens(context, *di, &dir)) + goto next_dir; +#endif - if (_krb5_expand_path_tokens(context, *di, &dir)) - continue; - d = opendir(dir); + trim_trailing_slash(dir); + + d = opendir(dir); - free(dir); - } -#else - d = opendir(*di); -#endif if (d == NULL) - continue; + goto next_dir; + rk_cloexec_dir(d); while ((entry = readdir(d)) != NULL) { char *n = entry->d_name; /* skip . and .. */ - if (n[0] == '.' && (n[1] == '\0' || (n[1] == '.' && n[2] == '\0'))) + if (!is_valid_plugin_filename(n)) continue; path = NULL; @@ -231,11 +267,11 @@ load_plugins(krb5_context context) { /* support loading bundles on MacOS */ size_t len = strlen(n); if (len > 7 && strcmp(&n[len - 7], ".bundle") == 0) - ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", *di, n, (int)(len - 7), n); + ret = asprintf(&path, "%s/%s/Contents/MacOS/%.*s", dir, n, (int)(len - 7), n); } #endif if (ret < 0 || path == NULL) - ret = asprintf(&path, "%s/%s", *di, n); + ret = asprintf(&path, "%s/%s", dir, n); if (ret < 0 || path == NULL) { ret = ENOMEM; @@ -254,6 +290,10 @@ load_plugins(krb5_context context) } } closedir(d); + + next_dir: + if (dir != *di) + free(dir); } if (dirs != rk_UNCONST(sysplugin_dirs)) krb5_config_free_strings(dirs); diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 8e6341fd62..42169fc2f9 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -721,7 +721,7 @@ krb5_build_principal(krb5_context context, * @ingroup krb5_principal */ -krb5_error_code KRB5_LIB_FUNCTION +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_make_principal(krb5_context context, krb5_principal *principal, krb5_const_realm realm, @@ -1013,437 +1013,6 @@ krb5_principal_match(krb5_context context, return TRUE; } -#if defined(KRB4) || !defined(HEIMDAL_SMALLER) - -static struct v4_name_convert { - const char *from; - const char *to; -} default_v4_name_convert[] = { - { "ftp", "ftp" }, - { "hprop", "hprop" }, - { "pop", "pop" }, - { "imap", "imap" }, - { "rcmd", "host" }, - { "smtp", "smtp" }, - { NULL, NULL } -}; - -#endif - -#ifdef KRB4 - -/* - * return the converted instance name of `name' in `realm'. - * look in the configuration file and then in the default set above. - * return NULL if no conversion is appropriate. - */ - -static const char* -get_name_conversion(krb5_context context, const char *realm, const char *name) -{ - struct v4_name_convert *q; - const char *p; - - p = krb5_config_get_string(context, NULL, "realms", realm, - "v4_name_convert", "host", name, NULL); - if(p == NULL) - p = krb5_config_get_string(context, NULL, "libdefaults", - "v4_name_convert", "host", name, NULL); - if(p) - return p; - - /* XXX should be possible to override default list */ - p = krb5_config_get_string(context, NULL, - "realms", - realm, - "v4_name_convert", - "plain", - name, - NULL); - if(p) - return NULL; - p = krb5_config_get_string(context, NULL, - "libdefaults", - "v4_name_convert", - "plain", - name, - NULL); - if(p) - return NULL; - for(q = default_v4_name_convert; q->from; q++) - if(strcmp(q->from, name) == 0) - return q->to; - return NULL; -} - -/* - * convert the v4 principal `name.instance@realm' to a v5 principal in `princ'. - * if `resolve', use DNS. - * if `func', use that function for validating the conversion - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_425_conv_principal_ext2(krb5_context context, - const char *name, - const char *instance, - const char *realm, - krb5_boolean (*func)(krb5_context, - void *, krb5_principal), - void *funcctx, - krb5_boolean resolve, - krb5_principal *princ) -{ - const char *p; - krb5_error_code ret; - krb5_principal pr; - char host[MAXHOSTNAMELEN]; - char local_hostname[MAXHOSTNAMELEN]; - - /* do the following: if the name is found in the - `v4_name_convert:host' part, is assumed to be a `host' type - principal, and the instance is looked up in the - `v4_instance_convert' part. if not found there the name is - (optionally) looked up as a hostname, and if that doesn't yield - anything, the `default_domain' is appended to the instance - */ - - if(instance == NULL) - goto no_host; - if(instance[0] == 0){ - instance = NULL; - goto no_host; - } - p = get_name_conversion(context, realm, name); - if(p == NULL) - goto no_host; - name = p; - p = krb5_config_get_string(context, NULL, "realms", realm, - "v4_instance_convert", instance, NULL); - if(p){ - instance = p; - ret = krb5_make_principal(context, &pr, realm, name, instance, NULL); - if (ret) - return ret; - if(func == NULL || (*func)(context, funcctx, pr)){ - *princ = pr; - return 0; - } - krb5_free_principal(context, pr); - *princ = NULL; - krb5_clear_error_message (context); - return HEIM_ERR_V4_PRINC_NO_CONV; - } - if(resolve){ - krb5_boolean passed = FALSE; - char *inst = NULL; -#ifdef USE_RESOLVER - struct rk_dns_reply *r; - - r = rk_dns_lookup(instance, "aaaa"); - if (r) { - if (r->head && r->head->type == rk_ns_t_aaaa) { - inst = strdup(r->head->domain); - passed = TRUE; - } - rk_dns_free_data(r); - } else { - r = rk_dns_lookup(instance, "a"); - if (r) { - if(r->head && r->head->type == rk_ns_t_a) { - inst = strdup(r->head->domain); - passed = TRUE; - } - rk_dns_free_data(r); - } - } -#else - struct addrinfo hints, *ai; - - memset (&hints, 0, sizeof(hints)); - hints.ai_flags = AI_CANONNAME; - ret = getaddrinfo(instance, NULL, &hints, &ai); - if (ret == 0) { - const struct addrinfo *a; - for (a = ai; a != NULL; a = a->ai_next) { - if (a->ai_canonname != NULL) { - inst = strdup (a->ai_canonname); - passed = TRUE; - break; - } - } - freeaddrinfo (ai); - } -#endif - if (passed) { - if (inst == NULL) { - krb5_set_error_message(context, ENOMEM, - N_("malloc: out of memory", "")); - return ENOMEM; - } - strlwr(inst); - ret = krb5_make_principal(context, &pr, realm, name, inst, - NULL); - free (inst); - if(ret == 0) { - if(func == NULL || (*func)(context, funcctx, pr)){ - *princ = pr; - return 0; - } - krb5_free_principal(context, pr); - } - } - } - if(func != NULL) { - snprintf(host, sizeof(host), "%s.%s", instance, realm); - strlwr(host); - ret = krb5_make_principal(context, &pr, realm, name, host, NULL); - if (ret) - return ret; - if((*func)(context, funcctx, pr)){ - *princ = pr; - return 0; - } - krb5_free_principal(context, pr); - } - - /* - * if the instance is the first component of the local hostname, - * the converted host should be the long hostname. - */ - - if (func == NULL && - gethostname (local_hostname, sizeof(local_hostname)) == 0 && - strncmp(instance, local_hostname, strlen(instance)) == 0 && - local_hostname[strlen(instance)] == '.') { - strlcpy(host, local_hostname, sizeof(host)); - goto local_host; - } - - { - char **domains, **d; - domains = krb5_config_get_strings(context, NULL, "realms", realm, - "v4_domains", NULL); - for(d = domains; d && *d; d++){ - snprintf(host, sizeof(host), "%s.%s", instance, *d); - ret = krb5_make_principal(context, &pr, realm, name, host, NULL); - if (ret) { - krb5_config_free_strings(domains); - return ret; - } - if(func == NULL || (*func)(context, funcctx, pr)){ - *princ = pr; - krb5_config_free_strings(domains); - return 0; - } - krb5_free_principal(context, pr); - } - krb5_config_free_strings(domains); - } - - - p = krb5_config_get_string(context, NULL, "realms", realm, - "default_domain", NULL); - if(p == NULL){ - /* this should be an error, just faking a name is not good */ - krb5_clear_error_message (context); - return HEIM_ERR_V4_PRINC_NO_CONV; - } - - if (*p == '.') - ++p; - snprintf(host, sizeof(host), "%s.%s", instance, p); -local_host: - ret = krb5_make_principal(context, &pr, realm, name, host, NULL); - if (ret) - return ret; - if(func == NULL || (*func)(context, funcctx, pr)){ - *princ = pr; - return 0; - } - krb5_free_principal(context, pr); - krb5_clear_error_message (context); - return HEIM_ERR_V4_PRINC_NO_CONV; -no_host: - p = krb5_config_get_string(context, NULL, - "realms", - realm, - "v4_name_convert", - "plain", - name, - NULL); - if(p == NULL) - p = krb5_config_get_string(context, NULL, - "libdefaults", - "v4_name_convert", - "plain", - name, - NULL); - if(p) - name = p; - - ret = krb5_make_principal(context, &pr, realm, name, instance, NULL); - if (ret) - return ret; - if(func == NULL || (*func)(context, funcctx, pr)){ - *princ = pr; - return 0; - } - krb5_free_principal(context, pr); - krb5_clear_error_message (context); - return HEIM_ERR_V4_PRINC_NO_CONV; -} - -#endif /* KRB4 */ - -#ifndef HEIMDAL_SMALLER - -static int -check_list(const krb5_config_binding *l, const char *name, const char **out) -{ - while(l){ - if (l->type != krb5_config_string) - continue; - if(strcmp(name, l->u.string) == 0) { - *out = l->name; - return 1; - } - l = l->next; - } - return 0; -} - -static int -name_convert(krb5_context context, const char *name, const char *realm, - const char **out) -{ - const krb5_config_binding *l; - l = krb5_config_get_list (context, - NULL, - "realms", - realm, - "v4_name_convert", - "host", - NULL); - if(l && check_list(l, name, out)) - return KRB5_NT_SRV_HST; - l = krb5_config_get_list (context, - NULL, - "libdefaults", - "v4_name_convert", - "host", - NULL); - if(l && check_list(l, name, out)) - return KRB5_NT_SRV_HST; - l = krb5_config_get_list (context, - NULL, - "realms", - realm, - "v4_name_convert", - "plain", - NULL); - if(l && check_list(l, name, out)) - return KRB5_NT_UNKNOWN; - l = krb5_config_get_list (context, - NULL, - "libdefaults", - "v4_name_convert", - "host", - NULL); - if(l && check_list(l, name, out)) - return KRB5_NT_UNKNOWN; - - /* didn't find it in config file, try built-in list */ -#ifdef KRB4 - { - struct v4_name_convert *q; - for(q = default_v4_name_convert; q->from; q++) { - if(strcmp(name, q->to) == 0) { - *out = q->from; - return KRB5_NT_SRV_HST; - } - } - } -#endif - return -1; -} - -/* - * convert the v5 principal in `principal' into a v4 corresponding one - * in `name, instance, realm' - * this is limited interface since there's no length given for these - * three parameters. They have to be 40 bytes each (ANAME_SZ). - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -krb5_524_conv_principal(krb5_context context, - const krb5_principal principal, - char *name, - char *instance, - char *realm) -{ - const char *n, *i, *r; - char tmpinst[40]; - int type = princ_type(principal); - const int aname_sz = 40; - - r = principal->realm; - - switch(principal->name.name_string.len){ - case 1: - n = principal->name.name_string.val[0]; - i = ""; - break; - case 2: - n = principal->name.name_string.val[0]; - i = principal->name.name_string.val[1]; - break; - default: - krb5_set_error_message(context, KRB5_PARSE_MALFORMED, - N_("cannot convert a %d " - "component principal", ""), - principal->name.name_string.len); - return KRB5_PARSE_MALFORMED; - } - - { - const char *tmp; - int t = name_convert(context, n, r, &tmp); - if(t >= 0) { - type = t; - n = tmp; - } - } - - if(type == KRB5_NT_SRV_HST){ - char *p; - - strlcpy (tmpinst, i, sizeof(tmpinst)); - p = strchr(tmpinst, '.'); - if(p) - *p = 0; - i = tmpinst; - } - - if (strlcpy (name, n, aname_sz) >= aname_sz) { - krb5_set_error_message(context, KRB5_PARSE_MALFORMED, - N_("too long name component to convert", "")); - return KRB5_PARSE_MALFORMED; - } - if (strlcpy (instance, i, aname_sz) >= aname_sz) { - krb5_set_error_message(context, KRB5_PARSE_MALFORMED, - N_("too long instance component to convert", "")); - return KRB5_PARSE_MALFORMED; - } - if (strlcpy (realm, r, aname_sz) >= aname_sz) { - krb5_set_error_message(context, KRB5_PARSE_MALFORMED, - N_("too long realm component to convert", "")); - return KRB5_PARSE_MALFORMED; - } - return 0; -} - -#endif /* !HEIMDAL_SMALLER */ - /** * Create a principal for the service running on hostname. If * KRB5_NT_SRV_HST is used, the hostname is canonization using DNS (or @@ -1536,7 +1105,7 @@ static const struct { * @ingroup krb5_principal */ -krb5_error_code +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) { size_t i; @@ -1558,7 +1127,7 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) * @ingroup krb5_principal */ -krb5_boolean +KRB5_LIB_FUNCTION krb5_boolean KRB5_LIB_CALL krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p) { return p->name.name_string.len == 2 && diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 45c97284bf..d816242f09 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -177,7 +177,7 @@ krb5_ticket_get_endtime(krb5_context context, * * @ingroup krb5_ticket */ -unsigned long +KRB5_LIB_FUNCTION unsigned long KRB5_LIB_CALL krb5_ticket_get_flags(krb5_context context, const krb5_ticket *ticket) { diff --git a/source4/heimdal/lib/krb5/v4_glue.c b/source4/heimdal/lib/krb5/v4_glue.c deleted file mode 100644 index d47a1288ed..0000000000 --- a/source4/heimdal/lib/krb5/v4_glue.c +++ /dev/null @@ -1,960 +0,0 @@ -/* - * Copyright (c) 1997 - 2005 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. - */ - -#include "krb5_locl.h" - -#include "krb5-v4compat.h" - -#ifndef HEIMDAL_SMALLER - -/* - * - */ - -#define RCHECK(r,func,label) \ - do { (r) = func ; if (r) goto label; } while(0); - - -/* include this here, to avoid dependencies on libkrb */ - -static const int _tkt_lifetimes[TKTLIFENUMFIXED] = { - 38400, 41055, 43894, 46929, 50174, 53643, 57352, 61318, - 65558, 70091, 74937, 80119, 85658, 91581, 97914, 104684, - 111922, 119661, 127935, 136781, 146239, 156350, 167161, 178720, - 191077, 204289, 218415, 233517, 249664, 266926, 285383, 305116, - 326213, 348769, 372885, 398668, 426234, 455705, 487215, 520904, - 556921, 595430, 636601, 680618, 727680, 777995, 831789, 889303, - 950794, 1016537, 1086825, 1161973, 1242318, 1328218, 1420057, 1518247, - 1623226, 1735464, 1855462, 1983758, 2120925, 2267576, 2424367, 2592000 -}; - -KRB5_LIB_FUNCTION int KRB5_LIB_CALL -_krb5_krb_time_to_life(time_t start, time_t end) -{ - int i; - time_t life = end - start; - - if (life > MAXTKTLIFETIME || life <= 0) - return 0; -#if 0 - if (krb_no_long_lifetimes) - return (life + 5*60 - 1)/(5*60); -#endif - - if (end >= NEVERDATE) - return TKTLIFENOEXPIRE; - if (life < _tkt_lifetimes[0]) - return (life + 5*60 - 1)/(5*60); - for (i=0; i TKTLIFEMAXFIXED) - return start + MAXTKTLIFETIME; - return start + _tkt_lifetimes[life - TKTLIFEMINFIXED]; -} - -/* - * Get the name of the krb4 credentials cache, will use `tkfile' as - * the name if that is passed in. `cc' must be free()ed by caller, - */ - -static krb5_error_code -get_krb4_cc_name(const char *tkfile, char **cc) -{ - - *cc = NULL; - if(tkfile == NULL) { - char *path; - if(!issuid()) { - path = getenv("KRBTKFILE"); - if (path) - *cc = strdup(path); - } -#ifdef HAVE_GETUID - if(*cc == NULL) - if (asprintf(cc, "%s%u", TKT_ROOT, (unsigned)getuid()) < 0 || *cc == NULL) - return errno; -#elif defined(KRB5_USE_PATH_TOKENS) - if(*cc == NULL) - if (_krb5_expand_path_tokens(NULL, TKT_ROOT "%{uid}", cc)) - return ENOMEM; -#endif - } else { - *cc = strdup(tkfile); - if (*cc == NULL) - return ENOMEM; - } - return 0; -} - -/* - * Write a Kerberos 4 ticket file - */ - -#define KRB5_TF_LCK_RETRY_COUNT 50 -#define KRB5_TF_LCK_RETRY 1 - -static krb5_error_code -write_v4_cc(krb5_context context, const char *tkfile, - krb5_storage *sp, int append) -{ - krb5_error_code ret; - struct stat sb; - krb5_data data; - char *path; - int fd, i; - - ret = get_krb4_cc_name(tkfile, &path); - if (ret) { - krb5_set_error_message(context, ret, - N_("Failed getting the krb4 credentials " - "cache name", "")); - return ret; - } - - fd = open(path, O_WRONLY|O_CREAT, 0600); - if (fd < 0) { - ret = errno; - krb5_set_error_message(context, ret, - N_("Failed opening krb4 credential cache " - "%s: %s", "path, error"), - path, strerror(ret)); - free(path); - return ret; - } - rk_cloexec(fd); - - if (fstat(fd, &sb) != 0 || !S_ISREG(sb.st_mode)) { - krb5_set_error_message(context, ret, - N_("krb4 credential cache %s is not a file", ""), - path); - free(path); - close(fd); - return KRB5_FCC_PERM; - } - - for (i = 0; i < KRB5_TF_LCK_RETRY_COUNT; i++) { - if (flock(fd, LOCK_EX | LOCK_NB) < 0) { - sleep(KRB5_TF_LCK_RETRY); - } else - break; - } - if (i == KRB5_TF_LCK_RETRY_COUNT) { - krb5_set_error_message(context, KRB5_FCC_PERM, - N_("Failed to lock credentail cache %s", ""), - path); - free(path); - close(fd); - return KRB5_FCC_PERM; - } - - if (!append) { - ret = ftruncate(fd, 0); - if (ret < 0) { - flock(fd, LOCK_UN); - krb5_set_error_message(context, KRB5_FCC_PERM, - N_("Failed to truncate krb4 cc %s", ""), - path); - free(path); - close(fd); - return KRB5_FCC_PERM; - } - } - ret = lseek(fd, 0L, SEEK_END); - if (ret < 0) { - ret = errno; - flock(fd, LOCK_UN); - free(path); - close(fd); - return ret; - } - - krb5_storage_to_data(sp, &data); - - ret = write(fd, data.data, data.length); - if (ret != data.length) - ret = KRB5_CC_IO; - else - ret = 0; - - krb5_data_free(&data); - - flock(fd, LOCK_UN); - free(path); - close(fd); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_tf_setup(krb5_context context, - struct credentials *v4creds, - const char *tkfile, - int append) -{ - krb5_error_code ret; - krb5_storage *sp; - - sp = krb5_storage_emem(); - if (sp == NULL) - return ENOMEM; - - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_HOST); - krb5_storage_set_eof_code(sp, KRB5_CC_IO); - - krb5_clear_error_message(context); - - if (!append) { - RCHECK(ret, krb5_store_stringz(sp, v4creds->pname), error); - RCHECK(ret, krb5_store_stringz(sp, v4creds->pinst), error); - } - - /* cred */ - RCHECK(ret, krb5_store_stringz(sp, v4creds->service), error); - RCHECK(ret, krb5_store_stringz(sp, v4creds->instance), error); - RCHECK(ret, krb5_store_stringz(sp, v4creds->realm), error); - ret = krb5_storage_write(sp, v4creds->session, 8); - if (ret != 8) { - ret = KRB5_CC_IO; - goto error; - } - RCHECK(ret, krb5_store_int32(sp, v4creds->lifetime), error); - RCHECK(ret, krb5_store_int32(sp, v4creds->kvno), error); - RCHECK(ret, krb5_store_int32(sp, v4creds->ticket_st.length), error); - - ret = krb5_storage_write(sp, v4creds->ticket_st.dat, - v4creds->ticket_st.length); - if (ret != v4creds->ticket_st.length) { - ret = KRB5_CC_IO; - goto error; - } - RCHECK(ret, krb5_store_int32(sp, v4creds->issue_date), error); - - ret = write_v4_cc(context, tkfile, sp, append); - - error: - krb5_storage_free(sp); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_dest_tkt(krb5_context context, const char *tkfile) -{ - krb5_error_code ret; - char *path; - - ret = get_krb4_cc_name(tkfile, &path); - if (ret) { - krb5_set_error_message(context, ret, - N_("Failed getting the krb4 credentials " - "cache name", "")); - return ret; - } - - if (unlink(path) < 0) { - ret = errno; - krb5_set_error_message(context, ret, - N_("Failed removing the cache %s " - "with error %s", "path, error"), - path, strerror(ret)); - } - free(path); - - return ret; -} - -/* - * - */ - -static krb5_error_code -decrypt_etext(krb5_context context, const krb5_keyblock *key, - const krb5_data *cdata, krb5_data *data) -{ - krb5_error_code ret; - krb5_crypto crypto; - - ret = krb5_crypto_init(context, key, ETYPE_DES_PCBC_NONE, &crypto); - if (ret) - return ret; - - ret = krb5_decrypt(context, crypto, 0, cdata->data, cdata->length, data); - krb5_crypto_destroy(context, crypto); - - return ret; -} - - -/* - * - */ - -static const char eightzeros[8] = "\x00\x00\x00\x00\x00\x00\x00\x00"; - -static krb5_error_code -storage_to_etext(krb5_context context, - krb5_storage *sp, - const krb5_keyblock *key, - krb5_data *enc_data) -{ - krb5_error_code ret; - krb5_crypto crypto; - krb5_ssize_t size; - krb5_data data; - - /* multiple of eight bytes, don't round up */ - - size = krb5_storage_seek(sp, 0, SEEK_END); - if (size < 0) - return KRB4ET_RD_AP_UNDEC; - size = ((size+7) & ~7) - size; - - ret = krb5_storage_write(sp, eightzeros, size); - if (ret != size) - return KRB4ET_RD_AP_UNDEC; - - ret = krb5_storage_to_data(sp, &data); - if (ret) - return ret; - - ret = krb5_crypto_init(context, key, ETYPE_DES_PCBC_NONE, &crypto); - if (ret) { - krb5_data_free(&data); - return ret; - } - - ret = krb5_encrypt(context, crypto, 0, data.data, data.length, enc_data); - - krb5_data_free(&data); - krb5_crypto_destroy(context, crypto); - - return ret; -} - -/* - * - */ - -static krb5_error_code -put_nir(krb5_storage *sp, const char *name, - const char *instance, const char *realm) -{ - krb5_error_code ret; - - RCHECK(ret, krb5_store_stringz(sp, name), error); - RCHECK(ret, krb5_store_stringz(sp, instance), error); - if (realm) { - RCHECK(ret, krb5_store_stringz(sp, realm), error); - } - error: - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_create_ticket(krb5_context context, - unsigned char flags, - const char *pname, - const char *pinstance, - const char *prealm, - int32_t paddress, - const krb5_keyblock *session, - int16_t life, - int32_t life_sec, - const char *sname, - const char *sinstance, - const krb5_keyblock *key, - krb5_data *enc_data) -{ - krb5_error_code ret; - krb5_storage *sp; - - krb5_data_zero(enc_data); - - sp = krb5_storage_emem(); - if (sp == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); - return ENOMEM; - } - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - RCHECK(ret, krb5_store_int8(sp, flags), error); - RCHECK(ret, put_nir(sp, pname, pinstance, prealm), error); - RCHECK(ret, krb5_store_int32(sp, ntohl(paddress)), error); - - /* session key */ - ret = krb5_storage_write(sp, - session->keyvalue.data, - session->keyvalue.length); - if (ret != session->keyvalue.length) { - ret = KRB4ET_INTK_PROT; - goto error; - } - - RCHECK(ret, krb5_store_int8(sp, life), error); - RCHECK(ret, krb5_store_int32(sp, life_sec), error); - RCHECK(ret, put_nir(sp, sname, sinstance, NULL), error); - - ret = storage_to_etext(context, sp, key, enc_data); - - error: - krb5_storage_free(sp); - if (ret) - krb5_set_error_message(context, ret, - N_("Failed to encode kerberos 4 ticket", "")); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_create_ciph(krb5_context context, - const krb5_keyblock *session, - const char *service, - const char *instance, - const char *realm, - uint32_t life, - unsigned char kvno, - const krb5_data *ticket, - uint32_t kdc_time, - const krb5_keyblock *key, - krb5_data *enc_data) -{ - krb5_error_code ret; - krb5_storage *sp; - - krb5_data_zero(enc_data); - - sp = krb5_storage_emem(); - if (sp == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); - return ENOMEM; - } - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - /* session key */ - ret = krb5_storage_write(sp, - session->keyvalue.data, - session->keyvalue.length); - if (ret != session->keyvalue.length) { - ret = KRB4ET_INTK_PROT; - goto error; - } - - RCHECK(ret, put_nir(sp, service, instance, realm), error); - RCHECK(ret, krb5_store_int8(sp, life), error); - RCHECK(ret, krb5_store_int8(sp, kvno), error); - RCHECK(ret, krb5_store_int8(sp, ticket->length), error); - ret = krb5_storage_write(sp, ticket->data, ticket->length); - if (ret != ticket->length) { - ret = KRB4ET_INTK_PROT; - goto error; - } - RCHECK(ret, krb5_store_int32(sp, kdc_time), error); - - ret = storage_to_etext(context, sp, key, enc_data); - - error: - krb5_storage_free(sp); - if (ret) - krb5_set_error_message(context, ret, - N_("Failed to encode kerberos 4 ticket", "")); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_create_auth_reply(krb5_context context, - const char *pname, - const char *pinst, - const char *prealm, - int32_t time_ws, - int n, - uint32_t x_date, - unsigned char kvno, - const krb5_data *cipher, - krb5_data *data) -{ - krb5_error_code ret; - krb5_storage *sp; - - krb5_data_zero(data); - - sp = krb5_storage_emem(); - if (sp == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); - return ENOMEM; - } - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error); - RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_KDC_REPLY), error); - RCHECK(ret, put_nir(sp, pname, pinst, prealm), error); - RCHECK(ret, krb5_store_int32(sp, time_ws), error); - RCHECK(ret, krb5_store_int8(sp, n), error); - RCHECK(ret, krb5_store_int32(sp, x_date), error); - RCHECK(ret, krb5_store_int8(sp, kvno), error); - RCHECK(ret, krb5_store_int16(sp, cipher->length), error); - ret = krb5_storage_write(sp, cipher->data, cipher->length); - if (ret != cipher->length) { - ret = KRB4ET_INTK_PROT; - goto error; - } - - ret = krb5_storage_to_data(sp, data); - - error: - krb5_storage_free(sp); - if (ret) - krb5_set_error_message(context, ret, - N_("Failed to encode kerberos 4 ticket", "")); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_cr_err_reply(krb5_context context, - const char *name, - const char *inst, - const char *realm, - uint32_t time_ws, - uint32_t e, - const char *e_string, - krb5_data *data) -{ - krb5_error_code ret; - krb5_storage *sp; - - krb5_data_zero(data); - - if (name == NULL) name = ""; - if (inst == NULL) inst = ""; - if (realm == NULL) realm = ""; - if (e_string == NULL) e_string = ""; - - sp = krb5_storage_emem(); - if (sp == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); - return ENOMEM; - } - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - RCHECK(ret, krb5_store_int8(sp, KRB_PROT_VERSION), error); - RCHECK(ret, krb5_store_int8(sp, AUTH_MSG_ERR_REPLY), error); - RCHECK(ret, put_nir(sp, name, inst, realm), error); - RCHECK(ret, krb5_store_int32(sp, time_ws), error); - /* If it is a Kerberos 4 error-code, remove the et BASE */ - if (e >= ERROR_TABLE_BASE_krb && e <= ERROR_TABLE_BASE_krb + 255) - e -= ERROR_TABLE_BASE_krb; - RCHECK(ret, krb5_store_int32(sp, e), error); - RCHECK(ret, krb5_store_stringz(sp, e_string), error); - - ret = krb5_storage_to_data(sp, data); - - error: - krb5_storage_free(sp); - if (ret) - krb5_set_error_message(context, ret, "Failed to encode kerberos 4 error"); - - return 0; -} - -static krb5_error_code -get_v4_stringz(krb5_storage *sp, char **str, size_t max_len) -{ - krb5_error_code ret; - - ret = krb5_ret_stringz(sp, str); - if (ret) - return ret; - if (strlen(*str) > max_len) { - free(*str); - *str = NULL; - return KRB4ET_INTK_PROT; - } - return 0; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_decomp_ticket(krb5_context context, - const krb5_data *enc_ticket, - const krb5_keyblock *key, - const char *local_realm, - char **sname, - char **sinstance, - struct _krb5_krb_auth_data *ad) -{ - krb5_error_code ret; - krb5_ssize_t size; - krb5_storage *sp = NULL; - krb5_data ticket; - unsigned char des_key[8]; - - memset(ad, 0, sizeof(*ad)); - krb5_data_zero(&ticket); - - *sname = NULL; - *sinstance = NULL; - - RCHECK(ret, decrypt_etext(context, key, enc_ticket, &ticket), error); - - sp = krb5_storage_from_data(&ticket); - if (sp == NULL) { - krb5_data_free(&ticket); - krb5_set_error_message(context, ENOMEM, "alloc: out of memory"); - return ENOMEM; - } - - krb5_storage_set_eof_code(sp, KRB4ET_INTK_PROT); - - RCHECK(ret, krb5_ret_int8(sp, &ad->k_flags), error); - RCHECK(ret, get_v4_stringz(sp, &ad->pname, ANAME_SZ), error); - RCHECK(ret, get_v4_stringz(sp, &ad->pinst, INST_SZ), error); - RCHECK(ret, get_v4_stringz(sp, &ad->prealm, REALM_SZ), error); - RCHECK(ret, krb5_ret_uint32(sp, &ad->address), error); - - size = krb5_storage_read(sp, des_key, sizeof(des_key)); - if (size != sizeof(des_key)) { - ret = KRB4ET_INTK_PROT; - goto error; - } - - RCHECK(ret, krb5_ret_uint8(sp, &ad->life), error); - - if (ad->k_flags & 1) - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE); - else - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - RCHECK(ret, krb5_ret_uint32(sp, &ad->time_sec), error); - - RCHECK(ret, get_v4_stringz(sp, sname, ANAME_SZ), error); - RCHECK(ret, get_v4_stringz(sp, sinstance, INST_SZ), error); - - ret = krb5_keyblock_init(context, ETYPE_DES_PCBC_NONE, - des_key, sizeof(des_key), &ad->session); - if (ret) - goto error; - - if (strlen(ad->prealm) == 0) { - free(ad->prealm); - ad->prealm = strdup(local_realm); - if (ad->prealm == NULL) { - ret = ENOMEM; - goto error; - } - } - - error: - memset(des_key, 0, sizeof(des_key)); - if (sp) - krb5_storage_free(sp); - krb5_data_free(&ticket); - if (ret) { - if (*sname) { - free(*sname); - *sname = NULL; - } - if (*sinstance) { - free(*sinstance); - *sinstance = NULL; - } - _krb5_krb_free_auth_data(context, ad); - krb5_set_error_message(context, ret, "Failed to decode v4 ticket"); - } - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL -_krb5_krb_rd_req(krb5_context context, - krb5_data *authent, - const char *service, - const char *instance, - const char *local_realm, - int32_t from_addr, - const krb5_keyblock *key, - struct _krb5_krb_auth_data *ad) -{ - krb5_error_code ret; - krb5_storage *sp; - krb5_data ticket, eaut, aut; - krb5_ssize_t size; - int little_endian; - int8_t pvno; - int8_t type; - int8_t s_kvno; - uint8_t ticket_length; - uint8_t eaut_length; - uint8_t time_5ms; - char *realm = NULL; - char *sname = NULL; - char *sinstance = NULL; - char *r_realm = NULL; - char *r_name = NULL; - char *r_instance = NULL; - - uint32_t r_time_sec; /* Coarse time from authenticator */ - unsigned long delta_t; /* Time in authenticator - local time */ - long tkt_age; /* Age of ticket */ - - struct timeval tv; - - krb5_data_zero(&ticket); - krb5_data_zero(&eaut); - krb5_data_zero(&aut); - - sp = krb5_storage_from_data(authent); - if (sp == NULL) { - krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); - return ENOMEM; - } - - krb5_storage_set_eof_code(sp, KRB4ET_INTK_PROT); - - ret = krb5_ret_int8(sp, &pvno); - if (ret) { - krb5_set_error_message(context, ret, N_("Failed reading v4 pvno", "")); - goto error; - } - - if (pvno != KRB_PROT_VERSION) { - ret = KRB4ET_RD_AP_VERSION; - krb5_set_error_message(context, ret, N_("Failed v4 pvno not 4", "")); - goto error; - } - - ret = krb5_ret_int8(sp, &type); - if (ret) { - krb5_set_error_message(context, ret, N_("Failed readin v4 type", "")); - goto error; - } - - little_endian = type & 1; - type &= ~1; - - if(type != AUTH_MSG_APPL_REQUEST && type != AUTH_MSG_APPL_REQUEST_MUTUAL) { - ret = KRB4ET_RD_AP_MSG_TYPE; - krb5_set_error_message(context, ret, - N_("Not a valid v4 request type", "")); - goto error; - } - - RCHECK(ret, krb5_ret_int8(sp, &s_kvno), error); - RCHECK(ret, get_v4_stringz(sp, &realm, REALM_SZ), error); - RCHECK(ret, krb5_ret_uint8(sp, &ticket_length), error); - RCHECK(ret, krb5_ret_uint8(sp, &eaut_length), error); - RCHECK(ret, krb5_data_alloc(&ticket, ticket_length), error); - - size = krb5_storage_read(sp, ticket.data, ticket.length); - if (size != ticket.length) { - ret = KRB4ET_INTK_PROT; - krb5_set_error_message(context, ret, N_("Failed reading v4 ticket", "")); - goto error; - } - - /* Decrypt and take apart ticket */ - ret = _krb5_krb_decomp_ticket(context, &ticket, key, local_realm, - &sname, &sinstance, ad); - if (ret) - goto error; - - RCHECK(ret, krb5_data_alloc(&eaut, eaut_length), error); - - size = krb5_storage_read(sp, eaut.data, eaut.length); - if (size != eaut.length) { - ret = KRB4ET_INTK_PROT; - krb5_set_error_message(context, ret, - N_("Failed reading v4 authenticator", "")); - goto error; - } - - krb5_storage_free(sp); - sp = NULL; - - ret = decrypt_etext(context, &ad->session, &eaut, &aut); - if (ret) - goto error; - - sp = krb5_storage_from_data(&aut); - if (sp == NULL) { - ret = ENOMEM; - krb5_set_error_message(context, ret, N_("malloc: out of memory", "")); - goto error; - } - - if (little_endian) - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_LE); - else - krb5_storage_set_byteorder(sp, KRB5_STORAGE_BYTEORDER_BE); - - RCHECK(ret, get_v4_stringz(sp, &r_name, ANAME_SZ), error); - RCHECK(ret, get_v4_stringz(sp, &r_instance, INST_SZ), error); - RCHECK(ret, get_v4_stringz(sp, &r_realm, REALM_SZ), error); - - RCHECK(ret, krb5_ret_uint32(sp, &ad->checksum), error); - RCHECK(ret, krb5_ret_uint8(sp, &time_5ms), error); - RCHECK(ret, krb5_ret_uint32(sp, &r_time_sec), error); - - if (strcmp(ad->pname, r_name) != 0 || - strcmp(ad->pinst, r_instance) != 0 || - strcmp(ad->prealm, r_realm) != 0) { - ret = KRB4ET_RD_AP_INCON; - krb5_set_error_message(context, ret, N_("v4 principal mismatch", "")); - goto error; - } - - if (from_addr && ad->address && from_addr != ad->address) { - ret = KRB4ET_RD_AP_BADD; - krb5_set_error_message(context, ret, - N_("v4 bad address in ticket", "")); - goto error; - } - - gettimeofday(&tv, NULL); - delta_t = abs((int)(tv.tv_sec - r_time_sec)); - if (delta_t > CLOCK_SKEW) { - ret = KRB4ET_RD_AP_TIME; - krb5_set_error_message(context, ret, N_("v4 clock skew", "")); - goto error; - } - - /* Now check for expiration of ticket */ - - tkt_age = tv.tv_sec - ad->time_sec; - - if ((tkt_age < 0) && (-tkt_age > CLOCK_SKEW)) { - ret = KRB4ET_RD_AP_NYV; - krb5_set_error_message(context, ret, - N_("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_message(context, ret, N_("v4 ticket expired", "")); - goto error; - } - - ret = 0; - error: - krb5_data_free(&ticket); - krb5_data_free(&eaut); - krb5_data_free(&aut); - if (realm) - free(realm); - if (sname) - free(sname); - if (sinstance) - free(sinstance); - if (r_name) - free(r_name); - if (r_instance) - free(r_instance); - if (r_realm) - free(r_realm); - if (sp) - krb5_storage_free(sp); - - if (ret) - krb5_clear_error_message(context); - - return ret; -} - -/* - * - */ - -KRB5_LIB_FUNCTION void KRB5_LIB_CALL -_krb5_krb_free_auth_data(krb5_context context, struct _krb5_krb_auth_data *ad) -{ - if (ad->pname) - free(ad->pname); - if (ad->pinst) - free(ad->pinst); - if (ad->prealm) - free(ad->prealm); - krb5_free_keyblock_contents(context, &ad->session); - memset(ad, 0, sizeof(*ad)); -} - -#endif /* HEIMDAL_SMALLER */ diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index 63994dfca7..f7581d1f90 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -182,6 +182,7 @@ krb5_verr(krb5_context context, int eval, krb5_error_code code, { _warnerr(context, 1, code, 0, fmt, ap); exit(eval); + UNREACHABLE(return 0); } /** @@ -203,6 +204,7 @@ krb5_err(krb5_context context, int eval, krb5_error_code code, { FUNC(1, code, 0); exit(eval); + UNREACHABLE(return 0); } /** @@ -222,6 +224,7 @@ krb5_verrx(krb5_context context, int eval, const char *fmt, va_list ap) { _warnerr(context, 0, 0, 0, fmt, ap); exit(eval); + UNREACHABLE(return 0); } /** @@ -240,6 +243,7 @@ krb5_errx(krb5_context context, int eval, const char *fmt, ...) { FUNC(0, 0, 0); exit(eval); + UNREACHABLE(return 0); } /** @@ -261,6 +265,7 @@ krb5_vabort(krb5_context context, krb5_error_code code, { _warnerr(context, 1, code, 0, fmt, ap); abort(); + UNREACHABLE(return 0); } /** @@ -280,6 +285,7 @@ krb5_abort(krb5_context context, krb5_error_code code, const char *fmt, ...) { FUNC(1, code, 0); abort(); + UNREACHABLE(return 0); } KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL @@ -288,6 +294,7 @@ krb5_vabortx(krb5_context context, const char *fmt, va_list ap) { _warnerr(context, 0, 0, 0, fmt, ap); abort(); + UNREACHABLE(return 0); } /** @@ -306,6 +313,7 @@ krb5_abortx(krb5_context context, const char *fmt, ...) { FUNC(0, 0, 0); abort(); + UNREACHABLE(return 0); } /** -- cgit