diff options
50 files changed, 1155 insertions, 367 deletions
diff --git a/source4/heimdal/kdc/kdc_locl.h b/source4/heimdal/kdc/kdc_locl.h index daf155839c..024937e763 100644 --- a/source4/heimdal/kdc/kdc_locl.h +++ b/source4/heimdal/kdc/kdc_locl.h @@ -67,6 +67,9 @@ extern const struct units _kdc_digestunits[]; extern struct timeval _kdc_now; #define kdc_time (_kdc_now.tv_sec) +extern char *runas_string; +extern char *chroot_string; + void loop(krb5_context context, krb5_kdc_configuration *config); diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index 53e9f54537..8edc07a49b 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -1208,19 +1208,13 @@ _kdc_as_rep(krb5_context context, (unsigned)abs(kdc_time - p.patimestamp), context->max_skew, client_name); -#if 1 - /* This code is from samba, needs testing */ + /* - * the following is needed to make windows clients - * to retry using the timestamp in the error message - * - * this is maybe a bug in windows to not trying when e_text - * is present... + * The following is needed to make windows clients to + * retry using the timestamp in the error message, if + * there is a e_text, they become unhappy. */ e_text = NULL; -#else - e_text = "Too large time skew"; -#endif goto out; } et.flags.pre_authent = 1; diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index 247cb575de..e016183615 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -65,12 +65,15 @@ _kdc_db_fetch(krb5_context context, "malformed request: " "enterprise name with %d name components", principal->name.name_string.len); + free(ent); return ret; } ret = krb5_parse_name(context, principal->name.name_string.val[0], &enterprise_principal); - if (ret) + if (ret) { + free(ent); return ret; + } principal = enterprise_principal; } @@ -98,7 +101,8 @@ _kdc_db_fetch(krb5_context context, } } free(ent); - krb5_set_error_message(context, HDB_ERR_NOENTRY, "no such entry found in hdb"); + krb5_set_error_message(context, HDB_ERR_NOENTRY, + "no such entry found in hdb"); return HDB_ERR_NOENTRY; } diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index 644eae0fe4..0d00ef2173 100644 --- a/source4/heimdal/kdc/pkinit.c +++ b/source4/heimdal/kdc/pkinit.c @@ -284,7 +284,7 @@ generate_dh_keyblock(krb5_context context, dh_gen_keylen = ECDH_compute_key(dh_gen_key, size, EC_KEY_get0_public_key(client_params->u.ecdh.public_key), client_params->u.ecdh.key, NULL); - ret = 0; + #endif /* HAVE_OPENSSL */ } else { ret = KRB5KRB_ERR_GENERIC; @@ -1450,8 +1450,10 @@ _kdc_pk_mk_pa_reply(krb5_context context, ret = krb5_generate_random_keyblock(context, sessionetype, sessionkey); - if (ret) + if (ret) { + free(buf); goto out; + } } else krb5_abortx(context, "PK-INIT internal error"); @@ -1981,12 +1983,14 @@ _kdc_pk_initialize(krb5_context context, hx509_name name; char *str; ret = hx509_cert_get_subject(cert, &name); - hx509_name_to_string(name, &str); - krb5_warnx(context, "WARNING Found KDC certificate (%s)" - "is missing the PK-INIT KDC EKU, this is bad for " - "interoperability.", str); - hx509_name_free(&name); - free(str); + if (ret == 0) { + hx509_name_to_string(name, &str); + krb5_warnx(context, "WARNING Found KDC certificate (%s)" + "is missing the PK-INIT KDC EKU, this is bad for " + "interoperability.", str); + hx509_name_free(&name); + free(str); + } } hx509_cert_free(cert); } else diff --git a/source4/heimdal/lib/asn1/der_get.c b/source4/heimdal/lib/asn1/der_get.c index 8144639b9a..aee565040f 100644 --- a/source4/heimdal/lib/asn1/der_get.c +++ b/source4/heimdal/lib/asn1/der_get.c @@ -198,6 +198,13 @@ der_get_bmp_string (const unsigned char *p, size_t len, for (i = 0; i < data->length; i++) { data->data[i] = (p[0] << 8) | p[1]; p += 2; + /* check for NUL in the middle of the string */ + if (data->data[i] == 0 && i != (data->length - 1)) { + free(data->data); + data->data = NULL; + data->length = 0; + return ASN1_BAD_CHARACTER; + } } if (size) *size = len; @@ -222,6 +229,13 @@ der_get_universal_string (const unsigned char *p, size_t len, for (i = 0; i < data->length; i++) { data->data[i] = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; p += 4; + /* check for NUL in the middle of the string */ + if (data->data[i] == 0 && i != (data->length - 1)) { + free(data->data); + data->data = NULL; + data->length = 0; + return ASN1_BAD_CHARACTER; + } } if (size) *size = len; return 0; diff --git a/source4/heimdal/lib/asn1/der_put.c b/source4/heimdal/lib/asn1/der_put.c index 7e71443da5..10fc002334 100644 --- a/source4/heimdal/lib/asn1/der_put.c +++ b/source4/heimdal/lib/asn1/der_put.c @@ -165,7 +165,6 @@ der_put_general_string (unsigned char *p, size_t len, if (len < slen) return ASN1_OVERFLOW; p -= slen; - len -= slen; memcpy (p+1, *str, slen); *size = slen; return 0; @@ -200,7 +199,6 @@ der_put_bmp_string (unsigned char *p, size_t len, if (len / 2 < data->length) return ASN1_OVERFLOW; p -= data->length * 2; - len -= data->length * 2; for (i = 0; i < data->length; i++) { p[1] = (data->data[i] >> 8) & 0xff; p[2] = data->data[i] & 0xff; @@ -218,7 +216,6 @@ der_put_universal_string (unsigned char *p, size_t len, if (len / 4 < data->length) return ASN1_OVERFLOW; p -= data->length * 4; - len -= data->length * 4; for (i = 0; i < data->length; i++) { p[1] = (data->data[i] >> 24) & 0xff; p[2] = (data->data[i] >> 16) & 0xff; @@ -244,7 +241,6 @@ der_put_octet_string (unsigned char *p, size_t len, if (len < data->length) return ASN1_OVERFLOW; p -= data->length; - len -= data->length; memcpy (p+1, data->data, data->length); *size = data->length; return 0; @@ -421,8 +417,7 @@ der_put_length_and_tag (unsigned char *p, size_t len, size_t len_val, e = der_put_tag (p, len, class, type, tag, &l); if(e) return e; - p -= l; - len -= l; + ret += l; *size = ret; return 0; @@ -459,7 +454,7 @@ der_put_bit_string (unsigned char *p, size_t len, if (len < data_size + 1) return ASN1_OVERFLOW; p -= data_size + 1; - len -= data_size + 1; + memcpy (p+2, data->data, data_size); if (data->length && (data->length % 8) != 0) p[1] = 8 - (data->length % 8); diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1 index 8edb0fde69..7080b095f8 100644 --- a/source4/heimdal/lib/asn1/krb5.asn1 +++ b/source4/heimdal/lib/asn1/krb5.asn1 @@ -16,7 +16,8 @@ NAME-TYPE ::= INTEGER { KRB5_NT_WELLKNOWN(11), -- Wellknown KRB5_NT_ENT_PRINCIPAL_AND_ID(-130), -- Windows 2000 UPN and SID KRB5_NT_MS_PRINCIPAL(-128), -- NT 4 style name - KRB5_NT_MS_PRINCIPAL_AND_ID(-129) -- NT style name and SID + KRB5_NT_MS_PRINCIPAL_AND_ID(-129), -- NT style name and SID + KRB5_NT_NTLM(-1200) -- NTLM name, realm is domain } -- message types diff --git a/source4/heimdal/lib/asn1/main.c b/source4/heimdal/lib/asn1/main.c index 115c82a9c7..5cef970d78 100644 --- a/source4/heimdal/lib/asn1/main.c +++ b/source4/heimdal/lib/asn1/main.c @@ -142,6 +142,10 @@ main(int argc, char **argv) } arg = calloc(2, sizeof(arg[0])); + if (arg == NULL) { + perror("calloc"); + exit(1); + } arg[0] = option_file; arg[1] = NULL; len = 1; @@ -150,7 +154,7 @@ main(int argc, char **argv) buf[strcspn(buf, "\n\r")] = '\0'; arg = realloc(arg, (len + 2) * sizeof(arg[0])); - if (argv == NULL) { + if (arg == NULL) { perror("malloc"); exit(1); } diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 91141808f5..6052ec8134 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -63,6 +63,14 @@ #endif #endif +#ifdef __cplusplus +#define GSSAPI_CPP_START extern "C" { +#define GSSAPI_CPP_END } +#else +#define GSSAPI_CPP_START +#define GSSAPI_CPP_END +#endif + /* * Now define the three implementation-dependent types. */ @@ -243,9 +251,7 @@ typedef OM_uint32 gss_qop_t; #define GSS_IOV_BUFFER_TYPE(_t) ((_t) & ~GSS_IOV_BUFFER_TYPE_FLAG_MASK) #define GSS_IOV_BUFFER_FLAGS(_t) ((_t) & GSS_IOV_BUFFER_TYPE_FLAG_MASK) -#ifdef __cplusplus -extern "C" { -#endif +GSSAPI_CPP_START /* * The implementation must reserve static storage for a @@ -894,8 +900,17 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_release_iov_buffer(OM_uint32 *, gss_iov_buffer_desc *, int); -#ifdef __cplusplus -} -#endif +OM_uint32 GSSAPI_LIB_FUNCTION +gss_export_cred(OM_uint32 * /* minor_status */, + gss_cred_id_t /* cred_handle */, + gss_buffer_t /* cred_token */); + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_import_cred(OM_uint32 * /* minor_status */, + gss_buffer_t /* cred_token */, + gss_cred_id_t * /* cred_handle */); + + +GSSAPI_CPP_END #endif /* GSSAPI_GSSAPI_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h index 0baccf5098..4d004d90b5 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_krb5.h @@ -38,9 +38,7 @@ #include <gssapi.h> -#ifdef __cplusplus -extern "C" { -#endif +GSSAPI_CPP_START #if !defined(__GNUC__) && !defined(__attribute__) #define __attribute__(x) @@ -246,8 +244,6 @@ gss_krb5_set_allowable_enctypes(OM_uint32 *minor_status, OM_uint32 num_enctypes, int32_t *enctypes); -#ifdef __cplusplus -} -#endif +GSSAPI_CPP_END #endif /* GSSAPI_SPNEGO_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h index 3c4869f08d..c5d372d6dc 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi_spnego.h @@ -38,9 +38,7 @@ #include <gssapi.h> -#ifdef __cplusplus -extern "C" { -#endif +GSSAPI_CPP_START /* * RFC2478, SPNEGO: @@ -51,8 +49,6 @@ extern "C" { extern GSSAPI_LIB_VARIABLE gss_OID GSS_SPNEGO_MECHANISM; #define gss_mech_spnego GSS_SPNEGO_MECHANISM -#ifdef __cplusplus -} -#endif +GSSAPI_CPP_END #endif /* GSSAPI_SPNEGO_H_ */ diff --git a/source4/heimdal/lib/gssapi/gssapi_mech.h b/source4/heimdal/lib/gssapi/gssapi_mech.h index 6470df30a0..206a24ef74 100644 --- a/source4/heimdal/lib/gssapi/gssapi_mech.h +++ b/source4/heimdal/lib/gssapi/gssapi_mech.h @@ -343,6 +343,15 @@ _gss_store_cred_t(OM_uint32 *minor_status, gss_OID_set *elements_stored, gss_cred_usage_t *cred_usage_stored); +typedef OM_uint32 +_gss_export_cred_t(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t cred_token); + +typedef OM_uint32 +_gss_import_cred_t(OM_uint32 * minor_status, + gss_buffer_t cred_token, + gss_cred_id_t * cred_handle); #define GMI_VERSION 2 @@ -389,6 +398,8 @@ typedef struct gssapi_mech_interface_desc { _gss_unwrap_iov_t *gm_unwrap_iov; _gss_wrap_iov_length_t *gm_wrap_iov_length; _gss_store_cred_t *gm_store_cred; + _gss_export_cred_t *gm_export_cred; + _gss_import_cred_t *gm_import_cred; } gssapi_mech_interface_desc, *gssapi_mech_interface; gssapi_mech_interface diff --git a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c index 8d998ed098..355d1c4332 100644 --- a/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/accept_sec_context.c @@ -170,12 +170,12 @@ gsskrb5_accept_delegated_token if (delegated_cred_handle) { gsskrb5_cred handle; - - ret = _gsskrb5_import_cred(minor_status, - ccache, - NULL, - NULL, - delegated_cred_handle); + + ret = _gsskrb5_krb5_import_cred(minor_status, + ccache, + NULL, + NULL, + delegated_cred_handle); if (ret != GSS_S_COMPLETE) goto out; diff --git a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c index 4f6f38e674..696171dcfa 100644 --- a/source4/heimdal/lib/gssapi/krb5/acquire_cred.c +++ b/source4/heimdal/lib/gssapi/krb5/acquire_cred.c @@ -339,8 +339,8 @@ OM_uint32 _gsskrb5_acquire_cred if (desired_name != GSS_C_NO_NAME) { - ret = _gsskrb5_canon_name(minor_status, context, 0, desired_name, - &handle->principal); + ret = _gsskrb5_canon_name(minor_status, context, 0, NULL, + desired_name, &handle->principal); if (ret) { HEIMDAL_MUTEX_destroy(&handle->cred_id_mutex); free(handle); diff --git a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c index 7e0c3fe727..3de55d6e32 100644 --- a/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c +++ b/source4/heimdal/lib/gssapi/krb5/canonicalize_name.c @@ -48,7 +48,7 @@ OM_uint32 _gsskrb5_canonicalize_name ( GSSAPI_KRB5_INIT (&context); - ret = _gsskrb5_canon_name(minor_status, context, 1, input_name, &name); + ret = _gsskrb5_canon_name(minor_status, context, 1, NULL, input_name, &name); if (ret) return ret; diff --git a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c index a4b28f91ed..4e65fc1cf3 100644 --- a/source4/heimdal/lib/gssapi/krb5/copy_ccache.c +++ b/source4/heimdal/lib/gssapi/krb5/copy_ccache.c @@ -63,11 +63,11 @@ gss_krb5_copy_ccache(OM_uint32 *minor_status, OM_uint32 -_gsskrb5_import_cred(OM_uint32 *minor_status, - krb5_ccache id, - krb5_principal keytab_principal, - krb5_keytab keytab, - gss_cred_id_t *cred) +_gsskrb5_krb5_import_cred(OM_uint32 *minor_status, + krb5_ccache id, + krb5_principal keytab_principal, + krb5_keytab keytab, + gss_cred_id_t *cred) { krb5_context context; krb5_error_code kret; diff --git a/source4/heimdal/lib/gssapi/krb5/creds.c b/source4/heimdal/lib/gssapi/krb5/creds.c new file mode 100644 index 0000000000..c9befe9d77 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/creds.c @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2009 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 "gsskrb5_locl.h" + +OM_uint32 +_gsskrb5_export_cred(OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t cred_token) +{ + gsskrb5_cred handle = (gsskrb5_cred)cred_handle; + krb5_context context; + krb5_error_code ret; + krb5_storage *sp; + krb5_data data, mech; + const char *type; + char *str; + + GSSAPI_KRB5_INIT (&context); + + if (handle->usage != GSS_C_INITIATE && handle->usage != GSS_C_BOTH) { + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return GSS_S_FAILURE; + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + type = krb5_cc_get_type(context, handle->ccache); + if (strcmp(type, "MEMORY") == 0) { + krb5_creds *creds; + ret = krb5_store_uint32(sp, 0); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = _krb5_get_krbtgt(context, handle->ccache, + handle->principal->realm, + &creds); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_creds(sp, creds); + krb5_free_creds(context, creds); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + } else { + ret = krb5_store_uint32(sp, 1); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_get_full_name(context, handle->ccache, &str); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_string(sp, str); + free(str); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + } + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + sp = krb5_storage_emem(); + if (sp == NULL) { + krb5_data_free(&data); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + mech.data = GSS_KRB5_MECHANISM->elements; + mech.length = GSS_KRB5_MECHANISM->length; + + ret = krb5_store_data(sp, mech); + if (ret) { + krb5_data_free(&data); + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_store_data(sp, data); + krb5_data_free(&data); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + cred_token->value = data.data; + cred_token->length = data.length; + + return GSS_S_COMPLETE; +} + +OM_uint32 +_gsskrb5_import_cred(OM_uint32 * minor_status, + gss_buffer_t cred_token, + gss_cred_id_t * cred_handle) +{ + krb5_context context; + krb5_error_code ret; + gsskrb5_cred handle; + krb5_ccache id; + krb5_storage *sp; + char *str; + uint32_t type; + int flags = 0; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + GSSAPI_KRB5_INIT (&context); + + sp = krb5_storage_from_mem(cred_token->value, cred_token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + ret = krb5_ret_uint32(sp, &type); + if (ret) { + krb5_storage_free(sp); + *minor_status = ret; + return GSS_S_FAILURE; + } + switch (type) { + case 0: { + krb5_creds creds; + + ret = krb5_ret_creds(sp, &creds); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_initialize(context, id, creds.client); + if (ret) { + krb5_cc_destroy(context, id); + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_store_cred(context, id, &creds); + krb5_free_cred_contents(context, &creds); + + flags |= GSS_CF_DESTROY_CRED_ON_RELEASE; + + break; + } + case 1: + ret = krb5_ret_string(sp, &str); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + ret = krb5_cc_resolve(context, str, &id); + krb5_xfree(str); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + break; + + default: + krb5_storage_free(sp); + *minor_status = 0; + return GSS_S_NO_CRED; + } + + handle = calloc(1, sizeof(*handle)); + if (handle == NULL) { + krb5_cc_close(context, id); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + handle->usage = GSS_C_INITIATE; + krb5_cc_get_principal(context, id, &handle->principal); + handle->ccache = id; + handle->cred_flags = flags; + + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/krb5/external.c b/source4/heimdal/lib/gssapi/krb5/external.c index df23776a63..fc835bd845 100644 --- a/source4/heimdal/lib/gssapi/krb5/external.c +++ b/source4/heimdal/lib/gssapi/krb5/external.c @@ -470,7 +470,10 @@ static gssapi_mech_interface_desc krb5_mech = { _gsskrb5_pseudo_random, _gk_wrap_iov, _gk_unwrap_iov, - _gk_wrap_iov_length + _gk_wrap_iov_length, + _gsskrb5_store_cred, + _gsskrb5_export_cred, + _gsskrb5_import_cred }; gssapi_mech_interface diff --git a/source4/heimdal/lib/gssapi/krb5/import_name.c b/source4/heimdal/lib/gssapi/krb5/import_name.c index d488ce754b..f1aca93ffd 100644 --- a/source4/heimdal/lib/gssapi/krb5/import_name.c +++ b/source4/heimdal/lib/gssapi/krb5/import_name.c @@ -83,9 +83,10 @@ import_krb5_name (OM_uint32 *minor_status, OM_uint32 _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context, - int use_dns, gss_name_t name, krb5_principal *out) + int use_dns, krb5_const_principal sourcename, gss_name_t targetname, + krb5_principal *out) { - krb5_principal p = (krb5_principal)name; + krb5_principal p = (krb5_principal)targetname; krb5_error_code ret; char *hostname = NULL, *service; @@ -96,8 +97,11 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context, ret = krb5_copy_principal(context, p, out); } else if (!use_dns) { ret = krb5_copy_principal(context, p, out); - if (ret == 0) - krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST); + if (ret) + goto out; + krb5_principal_set_type(context, *out, KRB5_NT_SRV_HST); + if (sourcename) + ret = krb5_principal_set_realm(context, *out, sourcename->realm); } else { if (p->name.name_string.len == 0) return GSS_S_BAD_NAME; @@ -113,6 +117,7 @@ _gsskrb5_canon_name(OM_uint32 *minor_status, krb5_context context, out); } + out: if (ret) { *minor_status = ret; return GSS_S_FAILURE; diff --git a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c index 35ab9dd88d..b269d06798 100644 --- a/source4/heimdal/lib/gssapi/krb5/init_sec_context.c +++ b/source4/heimdal/lib/gssapi/krb5/init_sec_context.c @@ -191,7 +191,7 @@ gsskrb5_get_creds( } ret = _gsskrb5_canon_name(minor_status, context, use_dns, - target_name, &ctx->target); + ctx->source, target_name, &ctx->target); if (ret) return ret; diff --git a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c index 15d7632e4c..ee29bf8c66 100644 --- a/source4/heimdal/lib/gssapi/krb5/set_cred_option.c +++ b/source4/heimdal/lib/gssapi/krb5/set_cred_option.c @@ -119,8 +119,8 @@ import_cred(OM_uint32 *minor_status, free(str); str = NULL; - major_stat = _gsskrb5_import_cred(minor_status, id, keytab_principal, - keytab, cred_handle); + major_stat = _gsskrb5_krb5_import_cred(minor_status, id, keytab_principal, + keytab, cred_handle); out: if (id) krb5_cc_close(context, id); diff --git a/source4/heimdal/lib/gssapi/krb5/store_cred.c b/source4/heimdal/lib/gssapi/krb5/store_cred.c new file mode 100644 index 0000000000..675a1d8e95 --- /dev/null +++ b/source4/heimdal/lib/gssapi/krb5/store_cred.c @@ -0,0 +1,116 @@ +/* + * Copyright (c) 2003 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 "gsskrb5_locl.h" + +OM_uint32 +_gsskrb5_store_cred(OM_uint32 *minor_status, + gss_cred_id_t input_cred_handle, + gss_cred_usage_t cred_usage, + const gss_OID desired_mech, + OM_uint32 overwrite_cred, + OM_uint32 default_cred, + gss_OID_set *elements_stored, + gss_cred_usage_t *cred_usage_stored) +{ + krb5_context context; + krb5_error_code ret; + gsskrb5_cred cred; + krb5_ccache id; + int destroy = 0; + + *minor_status = 0; + + if (cred_usage != GSS_C_INITIATE) { + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return GSS_S_FAILURE; + } + + if (gss_oid_equal(desired_mech, GSS_KRB5_MECHANISM) == 0) + return GSS_S_BAD_MECH; + + cred = (gsskrb5_cred)input_cred_handle; + if (cred == NULL) + return GSS_S_NO_CRED; + + GSSAPI_KRB5_INIT (&context); + + HEIMDAL_MUTEX_lock(&cred->cred_id_mutex); + if (cred->usage != cred_usage && cred->usage != GSS_C_BOTH) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = GSS_KRB5_S_G_BAD_USAGE; + return(GSS_S_FAILURE); + } + + if (cred->principal == NULL) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = GSS_KRB5_S_KG_TGT_MISSING; + return(GSS_S_FAILURE); + } + + /* write out cred to credential cache */ + + ret = krb5_cc_cache_match(context, cred->principal, &id); + if (ret) { + ret = krb5_cc_new_unique(context, NULL, NULL, &id); + if (ret) { + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = ret; + return(GSS_S_FAILURE); + } + destroy = 1; + } + + ret = krb5_cc_initialize(context, id, cred->principal); + if (ret == 0) + ret = krb5_cc_copy_match_f(context, cred->ccache, id, NULL, NULL, NULL); + if (ret) { + if (destroy) + krb5_cc_destroy(context, id); + else + krb5_cc_close(context, id); + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + *minor_status = ret; + return(GSS_S_FAILURE); + } + + if (default_cred) + krb5_cc_switch(context, id); + + krb5_cc_close(context, id); + + HEIMDAL_MUTEX_unlock(&cred->cred_id_mutex); + + *minor_status = 0; + return GSS_S_COMPLETE; +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_aeap.c b/source4/heimdal/lib/gssapi/mech/gss_aeap.c index 9c784f42de..9a1835a039 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_aeap.c +++ b/source4/heimdal/lib/gssapi/mech/gss_aeap.c @@ -66,11 +66,8 @@ gss_wrap_iov(OM_uint32 * minor_status, m = ctx->gc_mech; - if (m->gm_wrap_iov == NULL) { - if (minor_status) - *minor_status = 0; + if (m->gm_wrap_iov == NULL) return GSS_S_UNAVAILABLE; - } return (m->gm_wrap_iov)(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, conf_state, @@ -108,10 +105,8 @@ gss_unwrap_iov(OM_uint32 *minor_status, m = ctx->gc_mech; - if (m->gm_unwrap_iov == NULL) { - *minor_status = 0; + if (m->gm_unwrap_iov == NULL) return GSS_S_UNAVAILABLE; - } return (m->gm_unwrap_iov)(minor_status, ctx->gc_ctx, conf_state, qop_state, @@ -152,10 +147,8 @@ gss_wrap_iov_length(OM_uint32 * minor_status, m = ctx->gc_mech; - if (m->gm_wrap_iov_length == NULL) { - *minor_status = 0; + if (m->gm_wrap_iov_length == NULL) return GSS_S_UNAVAILABLE; - } return (m->gm_wrap_iov_length)(minor_status, ctx->gc_ctx, conf_req_flag, qop_req, conf_state, @@ -213,7 +206,8 @@ gss_context_query_attributes(OM_uint32 *minor_status, void *data, size_t len) { - *minor_status = 0; + if (minor_status) + *minor_status = 0; if (gss_oid_equal(GSS_C_ATTR_STREAM_SIZES, attribute)) { memset(data, 0, len); diff --git a/source4/heimdal/lib/gssapi/mech/gss_cred.c b/source4/heimdal/lib/gssapi/mech/gss_cred.c new file mode 100644 index 0000000000..66df50b55e --- /dev/null +++ b/source4/heimdal/lib/gssapi/mech/gss_cred.c @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2009 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 KTH 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 KTH AND ITS 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 KTH OR ITS 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 "mech_locl.h" +#include <krb5.h> + +/* + * format: any number of: + * mech-len: int32 + * mech-data: char * (not alligned) + * cred-len: int32 + * cred-data char * (not alligned) +*/ + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_export_cred(OM_uint32 * minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t token) +{ + struct _gss_cred *cred = (struct _gss_cred *)cred_handle; + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + krb5_error_code ret; + krb5_storage *sp; + OM_uint32 major; + krb5_data data; + + _mg_buffer_zero(token); + + if (cred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + if (mc->gmc_mech->gm_export_cred == NULL) { + *minor_status = 0; + return GSS_S_NO_CRED; + } + } + + sp = krb5_storage_emem(); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + SLIST_FOREACH(mc, &cred->gc_mc, gmc_link) { + + major = mc->gmc_mech->gm_export_cred(minor_status, + mc->gmc_cred, &buffer); + if (major) { + krb5_storage_free(sp); + return major; + } + + ret = krb5_storage_write(sp, buffer.value, buffer.length); + if (ret != buffer.length) { + gss_release_buffer(minor_status, &buffer); + krb5_storage_free(sp); + *minor_status = EINVAL; + return GSS_S_FAILURE; + } + gss_release_buffer(minor_status, &buffer); + } + + ret = krb5_storage_to_data(sp, &data); + krb5_storage_free(sp); + if (ret) { + *minor_status = ret; + return GSS_S_FAILURE; + } + + token->value = data.data; + token->length = data.length; + + return GSS_S_COMPLETE; +} + +OM_uint32 GSSAPI_LIB_FUNCTION +gss_import_cred(OM_uint32 * minor_status, + gss_buffer_t token, + gss_cred_id_t * cred_handle) +{ + gssapi_mech_interface m; + krb5_error_code ret; + struct _gss_cred *cred; + krb5_storage *sp = NULL; + OM_uint32 major, junk; + krb5_data data; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + if (token->length == 0) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + sp = krb5_storage_from_readonly_mem(token->value, token->length); + if (sp == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + cred = calloc(1, sizeof(struct _gss_cred)); + if (cred == NULL) { + krb5_storage_free(sp); + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + SLIST_INIT(&cred->gc_mc); + + *cred_handle = (gss_cred_id_t)cred; + + while(1) { + struct _gss_mechanism_cred *mc; + gss_buffer_desc buffer; + gss_cred_id_t mcred; + gss_OID_desc oid; + + ret = krb5_ret_data(sp, &data); + if (ret == HEIM_ERR_EOF) { + break; + } else if (ret) { + *minor_status = ret; + major = GSS_S_FAILURE; + goto out; + } + oid.elements = data.data; + oid.length = data.length; + + m = __gss_get_mechanism(&oid); + krb5_data_free(&data); + if (!m) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + if (m->gm_import_cred == NULL) { + *minor_status = 0; + major = GSS_S_BAD_MECH; + goto out; + } + + ret = krb5_ret_data(sp, &data); + if (ret) { + *minor_status = ret; + major = GSS_S_FAILURE; + goto out; + } + + buffer.value = data.data; + buffer.length = data.length; + + major = m->gm_import_cred(minor_status, + &buffer, &mcred); + krb5_data_free(&data); + if (major) { + goto out; + } + + mc = malloc(sizeof(struct _gss_mechanism_cred)); + if (mc == NULL) { + *minor_status = EINVAL; + major = GSS_S_FAILURE; + goto out; + } + + mc->gmc_mech = m; + mc->gmc_mech_oid = &m->gm_mech_oid; + mc->gmc_cred = mcred; + + SLIST_INSERT_HEAD(&cred->gc_mc, mc, gmc_link); + } + krb5_storage_free(sp); + sp = NULL; + + if (SLIST_EMPTY(&cred->gc_mc)) { + major = GSS_S_NO_CRED; + goto out; + } + + return GSS_S_COMPLETE; + + out: + if (sp) + krb5_storage_free(sp); + + gss_release_cred(&junk, cred_handle); + + return major; + +} diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c index ad07c60bda..c5e348d5c0 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c @@ -33,23 +33,28 @@ OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name(OM_uint32 *minor_status, gss_name_t *input_name) { - struct _gss_name *name = (struct _gss_name *) *input_name; + struct _gss_name *name; *minor_status = 0; - if (name) { - if (name->gn_type.elements) - free(name->gn_type.elements); - while (SLIST_FIRST(&name->gn_mn)) { - struct _gss_mechanism_name *mn; - mn = SLIST_FIRST(&name->gn_mn); - SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link); - mn->gmn_mech->gm_release_name(minor_status, - &mn->gmn_name); - free(mn); - } - gss_release_buffer(minor_status, &name->gn_value); - free(name); - *input_name = GSS_C_NO_NAME; + + if (input_name == NULL || *input_name == NULL) + return GSS_S_COMPLETE; + + name = (struct _gss_name *) *input_name; + + if (name->gn_type.elements) + free(name->gn_type.elements); + while (SLIST_FIRST(&name->gn_mn)) { + struct _gss_mechanism_name *mn; + mn = SLIST_FIRST(&name->gn_mn); + SLIST_REMOVE_HEAD(&name->gn_mn, gmn_link); + mn->gmn_mech->gm_release_name(minor_status, + &mn->gmn_name); + free(mn); } + gss_release_buffer(minor_status, &name->gn_value); + free(name); + *input_name = GSS_C_NO_NAME; + return (GSS_S_COMPLETE); } diff --git a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c index a3a984e22c..a10a10f1ef 100644 --- a/source4/heimdal/lib/gssapi/spnego/cred_stubs.c +++ b/source4/heimdal/lib/gssapi/spnego/cred_stubs.c @@ -354,3 +354,39 @@ _gss_spnego_set_cred_option (OM_uint32 *minor_status, value); } + +OM_uint32 +_gss_spnego_export_cred (OM_uint32 *minor_status, + gss_cred_id_t cred_handle, + gss_buffer_t value) +{ + gssspnego_cred cred = (gssspnego_cred)cred_handle; + + return gss_export_cred(minor_status, cred->negotiated_cred_id, value); +} + +OM_uint32 +_gss_spnego_import_cred (OM_uint32 *minor_status, + gss_buffer_t value, + gss_cred_id_t *cred_handle) +{ + gssspnego_cred cred; + OM_uint32 major; + + *cred_handle = GSS_C_NO_CREDENTIAL; + + cred = calloc(1, sizeof(*cred)); + if (cred == NULL) { + *minor_status = ENOMEM; + return GSS_S_FAILURE; + } + + major = gss_import_cred(minor_status, value, &cred->negotiated_cred_id); + if (major == GSS_S_COMPLETE) + *cred_handle = (gss_cred_id_t)cred; + else + free(cred); + + return major; +} + diff --git a/source4/heimdal/lib/gssapi/spnego/external.c b/source4/heimdal/lib/gssapi/spnego/external.c index 2dc809bbba..f3edcba389 100644 --- a/source4/heimdal/lib/gssapi/spnego/external.c +++ b/source4/heimdal/lib/gssapi/spnego/external.c @@ -79,7 +79,13 @@ static gssapi_mech_interface_desc spnego_mech = { _gss_spnego_inquire_cred_by_oid, _gss_spnego_set_sec_context_option, _gss_spnego_set_cred_option, - _gss_spnego_pseudo_random + _gss_spnego_pseudo_random, + NULL, + NULL, + NULL, + NULL, + _gss_spnego_export_cred, + _gss_spnego_import_cred }; gssapi_mech_interface diff --git a/source4/heimdal/lib/hcrypto/camellia-ntt.c b/source4/heimdal/lib/hcrypto/camellia-ntt.c index 358221162f..79c5a884ec 100644 --- a/source4/heimdal/lib/hcrypto/camellia-ntt.c +++ b/source4/heimdal/lib/hcrypto/camellia-ntt.c @@ -23,11 +23,7 @@ * http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html */ -#ifdef HAVE_CONFIG_H #include "config.h" -#endif - -#include <roken.h> #include <string.h> #include <stdlib.h> @@ -35,6 +31,8 @@ #include <krb5-types.h> #include "camellia-ntt.h" +#include <roken.h> + /* key constants */ #define CAMELLIA_SIGMA1L (0xA09E667FL) diff --git a/source4/heimdal/lib/hcrypto/camellia.c b/source4/heimdal/lib/hcrypto/camellia.c index d78bbd4c0e..c88822db5c 100644 --- a/source4/heimdal/lib/hcrypto/camellia.c +++ b/source4/heimdal/lib/hcrypto/camellia.c @@ -31,14 +31,8 @@ * SUCH DAMAGE. */ -#ifdef HAVE_CONFIG_H #include "config.h" -RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $"); -#endif - -#include <roken.h> - #ifdef KRB5 #include <krb5-types.h> #endif @@ -48,6 +42,8 @@ RCSID("$Id: aes.c 20466 2007-04-20 08:29:05Z lha $"); #include "camellia-ntt.h" #include "camellia.h" +#include <roken.h> + int CAMELLIA_set_key(const unsigned char *userkey, const int bits, CAMELLIA_KEY *key) diff --git a/source4/heimdal/lib/hdb/hdb.c b/source4/heimdal/lib/hdb/hdb.c index 9795f8b255..c5d91b8f9d 100644 --- a/source4/heimdal/lib/hdb/hdb.c +++ b/source4/heimdal/lib/hdb/hdb.c @@ -72,6 +72,7 @@ static struct hdb_method methods[] = { { HDB_INTERFACE_VERSION, "ldap:", hdb_ldap_create}, { HDB_INTERFACE_VERSION, "ldapi:", hdb_ldapi_create}, #endif + { HDB_INTERFACE_VERSION, "sqlite:", hdb_sqlite_create}, {0, NULL, NULL} }; diff --git a/source4/heimdal/lib/hdb/keytab.c b/source4/heimdal/lib/hdb/keytab.c index 2ec7837ae3..a557de036d 100644 --- a/source4/heimdal/lib/hdb/keytab.c +++ b/source4/heimdal/lib/hdb/keytab.c @@ -43,7 +43,7 @@ struct hdb_data { struct hdb_cursor { HDB *db; hdb_entry_ex hdb_entry; - bool first, next; + int first, next; int key_idx; }; @@ -272,7 +272,10 @@ hdb_start_seq_get(krb5_context context, HDB *db; if (dbname == NULL) { - /* We don't support enumerating without being told what backend to enumerate on */ + /* + * We don't support enumerating without being told what + * backend to enumerate on + */ ret = KRB5_KT_NOTFOUND; return ret; } @@ -301,91 +304,111 @@ hdb_start_seq_get(krb5_context context, } c->db = db; - c->first = true; - c->next = true; + c->first = TRUE; + c->next = TRUE; c->key_idx = 0; cursor->data = c; return ret; } -static int hdb_next_entry(krb5_context context, +static int +hdb_next_entry(krb5_context context, krb5_keytab id, krb5_keytab_entry *entry, krb5_kt_cursor *cursor) { - struct hdb_cursor *c = cursor->data; - krb5_error_code ret; - - if (c->first) { - c->first = false; - ret = (c->db->hdb_firstkey)(context, c->db, - HDB_F_DECRYPT| - HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, - &c->hdb_entry); - if (ret == HDB_ERR_NOENTRY) { - return KRB5_KT_END; - } else if (ret) { - return ret; - } - - if (c->hdb_entry.entry.keys.len == 0) { - hdb_free_entry(context, &c->hdb_entry); - } else { - c->next = false; - } - } - - while (c->next) { - ret = (c->db->hdb_nextkey)(context, c->db, - HDB_F_DECRYPT| - HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, - &c->hdb_entry); - if (ret == HDB_ERR_NOENTRY) { - return KRB5_KT_END; - } else if (ret) { - return ret; - } - if (c->hdb_entry.entry.keys.len == 0) { - /* If no keys on this entry, try again */ - hdb_free_entry(context, &c->hdb_entry); - } else { - /* We have an entry, set the flag */ - c->next = false; - } - }; - - /* return next enc type (keytabs are one slot per key, while hdb is one record per principal */ - krb5_copy_principal(context, - c->hdb_entry.entry.principal, - &entry->principal); - entry->vno = c->hdb_entry.entry.kvno; - krb5_copy_keyblock_contents(context, - &c->hdb_entry.entry.keys.val[c->key_idx].key, - &entry->keyblock); - c->key_idx++; - - /* Once we get to the end of the list, signal that we want the next entry */ - if (c->key_idx == c->hdb_entry.entry.keys.len) { - hdb_free_entry(context, &c->hdb_entry); - c->next = true; - c->key_idx = 0; - } - return 0; + struct hdb_cursor *c = cursor->data; + krb5_error_code ret; + + memset(entry, 0, sizeof(*entry)); + + if (c->first) { + c->first = FALSE; + ret = (c->db->hdb_firstkey)(context, c->db, + HDB_F_DECRYPT| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + &c->hdb_entry); + if (ret == HDB_ERR_NOENTRY) + return KRB5_KT_END; + else if (ret) + return ret; + + if (c->hdb_entry.entry.keys.len == 0) + hdb_free_entry(context, &c->hdb_entry); + else + c->next = FALSE; + } + + while (c->next) { + ret = (c->db->hdb_nextkey)(context, c->db, + HDB_F_DECRYPT| + HDB_F_GET_CLIENT|HDB_F_GET_SERVER|HDB_F_GET_KRBTGT, + &c->hdb_entry); + if (ret == HDB_ERR_NOENTRY) + return KRB5_KT_END; + else if (ret) + return ret; + + /* If no keys on this entry, try again */ + if (c->hdb_entry.entry.keys.len == 0) + hdb_free_entry(context, &c->hdb_entry); + else + c->next = FALSE; + } + + /* + * Return next enc type (keytabs are one slot per key, while + * hdb is one record per principal. + */ + + ret = krb5_copy_principal(context, + c->hdb_entry.entry.principal, + &entry->principal); + if (ret) + return ret; + + entry->vno = c->hdb_entry.entry.kvno; + ret = krb5_copy_keyblock_contents(context, + &c->hdb_entry.entry.keys.val[c->key_idx].key, + &entry->keyblock); + if (ret) { + krb5_free_principal(context, entry->principal); + memset(entry, 0, sizeof(*entry)); + return ret; + } + c->key_idx++; + + /* + * Once we get to the end of the list, signal that we want the + * next entry + */ + + if (c->key_idx == c->hdb_entry.entry.keys.len) { + hdb_free_entry(context, &c->hdb_entry); + c->next = TRUE; + c->key_idx = 0; + } + + return 0; } -static int hdb_end_seq_get(krb5_context context, - krb5_keytab id, - krb5_kt_cursor *cursor) { - struct hdb_cursor *c = cursor->data; - (c->db->hdb_close)(context, c->db); - (c->db->hdb_destroy)(context, c->db); - if (!c->next) { - hdb_free_entry(context, &c->hdb_entry); - } - free(c); - return 0; +static int +hdb_end_seq_get(krb5_context context, + krb5_keytab id, + krb5_kt_cursor *cursor) +{ + struct hdb_cursor *c = cursor->data; + + (c->db->hdb_close)(context, c->db); + (c->db->hdb_destroy)(context, c->db); + + if (!c->next) + hdb_free_entry(context, &c->hdb_entry); + + free(c); + return 0; } krb5_kt_ops hdb_kt_ops = { diff --git a/source4/heimdal/lib/hx509/ks_file.c b/source4/heimdal/lib/hx509/ks_file.c index 74808f7607..553191a774 100644 --- a/source4/heimdal/lib/hx509/ks_file.c +++ b/source4/heimdal/lib/hx509/ks_file.c @@ -340,7 +340,7 @@ pem_func(hx509_context context, const char *type, ret = (*formats[j].func)(context, NULL, pem_ctx->c, header, data, len, ai); - if (ret) { + if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL)) { hx509_set_error_string(context, HX509_ERROR_APPEND, ret, "Failed parseing PEM format %s", type); return ret; @@ -354,8 +354,6 @@ pem_func(hx509_context context, const char *type, "Found no matching PEM format for %s", type); return ret; } - if (ret && (pem_ctx->flags & HX509_CERTS_UNPROTECT_ALL)) - return ret; return 0; } diff --git a/source4/heimdal/lib/hx509/name.c b/source4/heimdal/lib/hx509/name.c index b8f48d5236..23736edde3 100644 --- a/source4/heimdal/lib/hx509/name.c +++ b/source4/heimdal/lib/hx509/name.c @@ -235,8 +235,10 @@ _hx509_Name_to_string(const Name *n, char **str) if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ ret = wind_ucs2utf8(bmp, bmplen, ss, NULL); - if (ret) + if (ret) { + free(ss); return ret; + } ss[k] = '\0'; break; } @@ -260,8 +262,10 @@ _hx509_Name_to_string(const Name *n, char **str) if (ss == NULL) _hx509_abort("allocation failure"); /* XXX */ ret = wind_ucs4utf8(uni, unilen, ss, NULL); - if (ret) + if (ret) { + free(ss); return ret; + } ss[k] = '\0'; break; } diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index a30780d1ed..42e2fdf359 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -3260,10 +3260,8 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(q, data[i].data.data, data[i].data.length); q += data[i].data.length; } - if (piv) { + if (piv) memset(q, 0, piv->data.length); - q += piv->data.length; - } ret = create_checksum(context, et->keyed_checksum, @@ -3299,10 +3297,9 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(q, data[i].data.data, data[i].data.length); q += data[i].data.length; } - if (piv) { + if (piv) memset(q, 0, piv->data.length); - q += piv->data.length; - } + ret = _get_derived_key(context, crypto, ENCRYPTION_USAGE(usage), &dkey); if(ret) { @@ -3333,10 +3330,8 @@ krb5_encrypt_iov_ivec(krb5_context context, memcpy(data[i].data.data, q, data[i].data.length); q += data[i].data.length; } - if (piv) { + if (piv) memcpy(piv->data.data, q, pad_sz); - q += pad_sz; - } free(p); diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index e609bcadcc..10417f1a52 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -652,13 +652,16 @@ krb5_get_kdc_cred(krb5_context context, &krbtgt); if(ret) { free(*out_creds); + *out_creds = NULL; return ret; } ret = get_cred_kdc(context, id, flags, addresses, in_creds, krbtgt, NULL, NULL, *out_creds); krb5_free_creds (context, krbtgt); - if(ret) + if(ret) { free(*out_creds); + *out_creds = NULL; + } return ret; } @@ -1038,15 +1041,15 @@ out: * codebase. */ -static krb5_error_code -get_cred_kdc_any(krb5_context context, - krb5_kdc_flags flags, - krb5_ccache ccache, - krb5_creds *in_creds, - krb5_principal impersonate_principal, - Ticket *second_ticket, - krb5_creds **out_creds, - krb5_creds ***ret_tgts) +krb5_error_code +_krb5_get_cred_kdc_any(krb5_context context, + krb5_kdc_flags flags, + krb5_ccache ccache, + krb5_creds *in_creds, + krb5_principal impersonate_principal, + Ticket *second_ticket, + krb5_creds **out_creds, + krb5_creds ***ret_tgts) { krb5_error_code ret; @@ -1072,33 +1075,6 @@ get_cred_kdc_any(krb5_context context, krb5_error_code KRB5_LIB_FUNCTION -krb5_get_cred_from_kdc_opt(krb5_context context, - krb5_ccache ccache, - krb5_creds *in_creds, - krb5_creds **out_creds, - krb5_creds ***ret_tgts, - krb5_flags flags) -{ - krb5_kdc_flags f; - f.i = flags; - return get_cred_kdc_any(context, f, ccache, - in_creds, NULL, NULL, - out_creds, ret_tgts); -} - -krb5_error_code KRB5_LIB_FUNCTION -krb5_get_cred_from_kdc(krb5_context context, - krb5_ccache ccache, - krb5_creds *in_creds, - krb5_creds **out_creds, - krb5_creds ***ret_tgts) -{ - return krb5_get_cred_from_kdc_opt(context, ccache, - in_creds, out_creds, ret_tgts, 0); -} - - -krb5_error_code KRB5_LIB_FUNCTION krb5_get_credentials_with_flags(krb5_context context, krb5_flags options, krb5_kdc_flags flags, @@ -1166,8 +1142,8 @@ krb5_get_credentials_with_flags(krb5_context context, options |= KRB5_GC_NO_STORE; tgts = NULL; - ret = get_cred_kdc_any(context, flags, ccache, - in_creds, NULL, NULL, out_creds, &tgts); + ret = _krb5_get_cred_kdc_any(context, flags, ccache, + in_creds, NULL, NULL, out_creds, &tgts); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); krb5_free_creds(context, tgts[i]); @@ -1387,9 +1363,9 @@ krb5_get_creds(krb5_context context, flags.b.canonicalize = 1; tgts = NULL; - ret = get_cred_kdc_any(context, flags, ccache, - &in_creds, opt->self, opt->ticket, - out_creds, &tgts); + ret = _krb5_get_cred_kdc_any(context, flags, ccache, + &in_creds, opt->self, opt->ticket, + out_creds, &tgts); krb5_free_principal(context, in_creds.client); for(i = 0; tgts && tgts[i]; i++) { krb5_cc_store_cred(context, ccache, tgts[i]); diff --git a/source4/heimdal/lib/krb5/kcm.c b/source4/heimdal/lib/krb5/kcm.c index f034341972..c94dea551f 100644 --- a/source4/heimdal/lib/krb5/kcm.c +++ b/source4/heimdal/lib/krb5/kcm.c @@ -1097,8 +1097,8 @@ _krb5_kcm_get_initial_ticket(krb5_context context, krb5_principal server, krb5_keyblock *key) { - krb5_error_code ret; krb5_kcmcache *k = KCMCACHE(id); + krb5_error_code ret; krb5_storage *request; ret = kcm_storage_request(context, KCM_OP_GET_INITIAL_TICKET, &request); diff --git a/source4/heimdal/lib/krb5/keytab_file.c b/source4/heimdal/lib/krb5/keytab_file.c index 819366443f..9a21db0cbb 100644 --- a/source4/heimdal/lib/krb5/keytab_file.c +++ b/source4/heimdal/lib/krb5/keytab_file.c @@ -490,7 +490,7 @@ loop: if(len + 4 + pos - curpos >= 8) { ret = krb5_ret_uint32(cursor->sp, &utmp32); if (ret == 0) - entry->flags = tmp32; + entry->flags = utmp32; } else entry->flags = 0; diff --git a/source4/heimdal/lib/krb5/log.c b/source4/heimdal/lib/krb5/log.c index ee5c1159b1..5b84bc2f4c 100644 --- a/source4/heimdal/lib/krb5/log.c +++ b/source4/heimdal/lib/krb5/log.c @@ -220,17 +220,16 @@ log_file(const char *timestr, { struct file_data *f = data; char *msgclean; - size_t len = strlen(msg) + 1; + size_t len = strlen(msg); if(f->keep_open == 0) f->fd = fopen(f->filename, f->mode); if(f->fd == NULL) return; /* make sure the log doesn't contain special chars */ - len *= 4; - msgclean = malloc(len); + msgclean = malloc((len + 1) * 4); if (msgclean == NULL) goto out; - strvisx(rk_UNCONST(msg), msgclean, len, VIS_OCTAL); + strvisx(msgclean, rk_UNCONST(msg), len, VIS_OCTAL); fprintf(f->fd, "%s %s\n", timestr, msgclean); free(msgclean); out: diff --git a/source4/heimdal/lib/krb5/pkinit.c b/source4/heimdal/lib/krb5/pkinit.c index 18b5b5e017..af5568f44b 100644 --- a/source4/heimdal/lib/krb5/pkinit.c +++ b/source4/heimdal/lib/krb5/pkinit.c @@ -1402,6 +1402,7 @@ pk_rd_pa_reply_dh(krb5_context context, kdc_dh_pubkey, ctx->u.dh); if (dh_gen_keylen == -1) { ret = KRB5KRB_ERR_GENERIC; + dh_gen_keylen = 0; krb5_set_error_message(context, ret, N_("PKINIT: Can't compute Diffie-Hellman key", "")); goto out; @@ -1446,6 +1447,7 @@ pk_rd_pa_reply_dh(krb5_context context, EC_KEY_free(public); if (dh_gen_keylen == -1) { ret = KRB5KRB_ERR_GENERIC; + dh_gen_keylen = 0; krb5_set_error_message(context, ret, N_("PKINIT: Can't compute ECDH public key", "")); goto out; @@ -1455,6 +1457,14 @@ pk_rd_pa_reply_dh(krb5_context context, #endif } + if (dh_gen_keylen <= 0) { + ret = EINVAL; + krb5_set_error_message(context, ret, + N_("PKINIT: resulting DH key <= 0", "")); + dh_gen_keylen = 0; + goto out; + } + *key = malloc (sizeof (**key)); if (*key == NULL) { ret = ENOMEM; diff --git a/source4/heimdal/lib/krb5/plugin.c b/source4/heimdal/lib/krb5/plugin.c index 844cb7ab88..027f2a72a7 100644 --- a/source4/heimdal/lib/krb5/plugin.c +++ b/source4/heimdal/lib/krb5/plugin.c @@ -40,19 +40,28 @@ struct krb5_plugin { void *symbol; - void *dsohandle; struct krb5_plugin *next; }; struct plugin { - enum krb5_plugin_type type; - void *name; - void *symbol; + enum { DSO, SYMBOL } type; + union { + struct { + char *path; + void *dsohandle; + } dso; + struct { + enum krb5_plugin_type type; + char *name; + char *symbol; + } symbol; + } u; struct plugin *next; }; static HEIMDAL_MUTEX plugin_mutex = HEIMDAL_MUTEX_INITIALIZER; static struct plugin *registered = NULL; +static int plugins_needs_scan = 1; static const char *sysplugin_dirs[] = { LIBDIR "/plugin/krb5", @@ -85,15 +94,14 @@ _krb5_plugin_get_next(struct krb5_plugin *p) #ifdef HAVE_DLOPEN static krb5_error_code -loadlib(krb5_context context, - enum krb5_plugin_type type, - const char *name, - const char *lib, - struct krb5_plugin **e) +loadlib(krb5_context context, char *path) { - *e = calloc(1, sizeof(**e)); - if (*e == NULL) { + struct plugin *e; + + e = calloc(1, sizeof(*e)); + if (e == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + free(path); return ENOMEM; } @@ -103,24 +111,13 @@ loadlib(krb5_context context, #ifndef RTLD_LOCAL #define RTLD_LOCAL 0 #endif + e->type = DSO; + /* ignore error from dlopen, and just keep it as negative cache entry */ + e->u.dso.dsohandle = dlopen(path, RTLD_LOCAL|RTLD_LAZY); + e->u.dso.path = path; - (*e)->dsohandle = dlopen(lib, RTLD_LOCAL|RTLD_LAZY); - if ((*e)->dsohandle == NULL) { - free(*e); - *e = NULL; - krb5_set_error_message(context, ENOMEM, "Failed to load %s: %s", - lib, dlerror()); - return ENOMEM; - } - - /* dlsym doesn't care about the type */ - (*e)->symbol = dlsym((*e)->dsohandle, name); - if ((*e)->symbol == NULL) { - dlclose((*e)->dsohandle); - free(*e); - krb5_clear_error_message(context); - return ENOMEM; - } + e->next = registered; + registered = e; return 0; } @@ -146,26 +143,35 @@ krb5_plugin_register(krb5_context context, { struct plugin *e; + HEIMDAL_MUTEX_lock(&plugin_mutex); + /* check for duplicates */ - for (e = registered; e != NULL; e = e->next) - if (e->type == type && strcmp(e->name,name)== 0 && e->symbol == symbol) + for (e = registered; e != NULL; e = e->next) { + if (e->type == SYMBOL && + strcmp(e->u.symbol.name, name) == 0 && + e->u.symbol.type == type && e->u.symbol.symbol == symbol) { + HEIMDAL_MUTEX_unlock(&plugin_mutex); return 0; + } + } e = calloc(1, sizeof(*e)); if (e == NULL) { + HEIMDAL_MUTEX_unlock(&plugin_mutex); krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - e->type = type; - e->name = strdup(name); - if (e->name == NULL) { + e->type = SYMBOL; + e->u.symbol.type = type; + e->u.symbol.name = strdup(name); + if (e->u.symbol.name == NULL) { + HEIMDAL_MUTEX_unlock(&plugin_mutex); free(e); krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - e->symbol = symbol; + e->u.symbol.symbol = symbol; - HEIMDAL_MUTEX_lock(&plugin_mutex); e->next = registered; registered = e; HEIMDAL_MUTEX_unlock(&plugin_mutex); @@ -173,41 +179,19 @@ krb5_plugin_register(krb5_context context, return 0; } -krb5_error_code -_krb5_plugin_find(krb5_context context, - enum krb5_plugin_type type, - const char *name, - struct krb5_plugin **list) +static krb5_error_code +load_plugins(krb5_context context) { - struct krb5_plugin *e; - struct plugin *p; + struct plugin *e; krb5_error_code ret; char **dirs = NULL, **di; struct dirent *entry; char *path; DIR *d = NULL; - *list = NULL; - - HEIMDAL_MUTEX_lock(&plugin_mutex); - - for (p = registered; p != NULL; p = p->next) { - if (p->type != type || strcmp(p->name, name) != 0) - continue; - - e = calloc(1, sizeof(*e)); - if (e == NULL) { - HEIMDAL_MUTEX_unlock(&plugin_mutex); - ret = ENOMEM; - krb5_set_error_message(context, ret, "malloc: out of memory"); - goto out; - } - e->symbol = p->symbol; - e->dsohandle = NULL; - e->next = *list; - *list = e; - } - HEIMDAL_MUTEX_unlock(&plugin_mutex); + if (!plugins_needs_scan) + return 0; + plugins_needs_scan = 0; #ifdef HAVE_DLOPEN @@ -244,21 +228,83 @@ _krb5_plugin_find(krb5_context context, if (path == NULL) { ret = ENOMEM; krb5_set_error_message(context, ret, "malloc: out of memory"); - goto out; + return ret; + } + + /* check if already tried */ + for (e = registered; e != NULL; e = e->next) + if (e->type == DSO && strcmp(e->u.dso.path, path) == 0) + break; + if (e) { + free(path); + } else { + loadlib(context, path); /* store or frees path */ } - ret = loadlib(context, type, name, path, &e); - free(path); - if (ret) - continue; - - e->next = *list; - *list = e; } closedir(d); } if (dirs != rk_UNCONST(sysplugin_dirs)) krb5_config_free_strings(dirs); #endif /* HAVE_DLOPEN */ + return 0; +} + +static krb5_error_code +add_symbol(krb5_context context, struct krb5_plugin **list, void *symbol) +{ + struct krb5_plugin *e; + + e = calloc(1, sizeof(*e)); + if (e == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + e->symbol = symbol; + e->next = *list; + *list = e; + return 0; +} + +krb5_error_code +_krb5_plugin_find(krb5_context context, + enum krb5_plugin_type type, + const char *name, + struct krb5_plugin **list) +{ + struct plugin *e; + krb5_error_code ret; + + *list = NULL; + + HEIMDAL_MUTEX_lock(&plugin_mutex); + + load_plugins(context); + + for (ret = 0, e = registered; e != NULL; e = e->next) { + switch(e->type) { + case DSO: { + void *sym; + if (e->u.dso.dsohandle == NULL) + continue; + sym = dlsym(e->u.dso.dsohandle, name); + if (sym) + ret = add_symbol(context, list, sym); + break; + } + case SYMBOL: + if (strcmp(e->u.symbol.name, name) == 0 && e->u.symbol.type == type) + ret = add_symbol(context, list, e->u.symbol.symbol); + break; + } + if (ret) { + _krb5_plugin_free(*list); + *list = NULL; + } + } + + HEIMDAL_MUTEX_unlock(&plugin_mutex); + if (ret) + return ret; if (*list == NULL) { krb5_set_error_message(context, ENOENT, "Did not find a plugin for %s", name); @@ -266,16 +312,6 @@ _krb5_plugin_find(krb5_context context, } return 0; - -out: - if (dirs != rk_UNCONST(sysplugin_dirs)) - krb5_config_free_strings(dirs); - if (d) - closedir(d); - _krb5_plugin_free(*list); - *list = NULL; - - return ret; } void @@ -284,8 +320,6 @@ _krb5_plugin_free(struct krb5_plugin *list) struct krb5_plugin *next; while (list) { next = list->next; - if (list->dsohandle) - dlclose(list->dsohandle); free(list); list = next; } diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 50b7bb8813..9899f5661f 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -496,6 +496,18 @@ unparse_name(krb5_context context, return ret; } +/** + * Unparse the Kerberos name into a string + * + * @param context Kerberos 5 context + * @param principal principal to query + * @param name resulting string, free with krb5_xfree() + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name(krb5_context context, krb5_const_principal principal, @@ -504,6 +516,19 @@ krb5_unparse_name(krb5_context context, return unparse_name(context, principal, name, 0); } +/** + * Unparse the Kerberos name into a string + * + * @param context Kerberos 5 context + * @param principal principal to query + * @param flags flag to determine the behavior + * @param name resulting string, free with krb5_xfree() + * + * @return An krb5 error code, see krb5_get_error_message(). + * + * @ingroup krb5_principal + */ + krb5_error_code KRB5_LIB_FUNCTION krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal, @@ -620,7 +645,6 @@ va_princ(krb5_context context, krb5_principal p, va_list ap) } } - static krb5_error_code build_principal(krb5_context context, krb5_principal *principal, @@ -733,8 +757,16 @@ krb5_copy_principal(krb5_context context, return 0; } -/* - * return TRUE iff princ1 == princ2 (without considering the realm) +/** + * Return TRUE iff princ1 == princ2 (without considering the realm) + * + * @param context Kerberos 5 context + * @param princ1 first principal to compare + * @param princ2 second principal to compare + * + * @return non zero if equal, 0 if not + * + * @ingroup krb5_principal */ krb5_boolean KRB5_LIB_FUNCTION diff --git a/source4/heimdal/lib/krb5/store_fd.c b/source4/heimdal/lib/krb5/store_fd.c index 38d67ae4d3..4150175927 100644 --- a/source4/heimdal/lib/krb5/store_fd.c +++ b/source4/heimdal/lib/krb5/store_fd.c @@ -79,7 +79,7 @@ fd_free(krb5_storage * sp) * * @ingroup krb5_storage * - * @sa krb5_storage_from_emem() + * @sa krb5_storage_emem() * @sa krb5_storage_from_mem() * @sa krb5_storage_from_readonly_mem() * @sa krb5_storage_from_data() diff --git a/source4/heimdal/lib/krb5/store_mem.c b/source4/heimdal/lib/krb5/store_mem.c index db1abc1e90..a7b0c2d2dc 100644 --- a/source4/heimdal/lib/krb5/store_mem.c +++ b/source4/heimdal/lib/krb5/store_mem.c @@ -116,7 +116,7 @@ mem_no_trunc(krb5_storage *sp, off_t offset) * * @ingroup krb5_storage * - * @sa krb5_storage_from_emem() + * @sa krb5_storage_mem() * @sa krb5_storage_from_readonly_mem() * @sa krb5_storage_from_data() * @sa krb5_storage_from_fd() @@ -155,7 +155,7 @@ krb5_storage_from_mem(void *buf, size_t len) * * @ingroup krb5_storage * - * @sa krb5_storage_from_emem() + * @sa krb5_storage_mem() * @sa krb5_storage_from_mem() * @sa krb5_storage_from_readonly_mem() * @sa krb5_storage_from_fd() @@ -174,7 +174,7 @@ krb5_storage_from_data(krb5_data *data) * * @ingroup krb5_storage * - * @sa krb5_storage_from_emem() + * @sa krb5_storage_mem() * @sa krb5_storage_from_mem() * @sa krb5_storage_from_data() * @sa krb5_storage_from_fd() diff --git a/source4/heimdal/lib/krb5/transited.c b/source4/heimdal/lib/krb5/transited.c index 196ef447ee..1ff4ce1658 100644 --- a/source4/heimdal/lib/krb5/transited.c +++ b/source4/heimdal/lib/krb5/transited.c @@ -62,9 +62,8 @@ static int make_path(krb5_context context, struct tr_realm *r, const char *from, const char *to) { - const char *p; - struct tr_realm *path = r->next; struct tr_realm *tmp; + const char *p; if(strlen(from) < strlen(to)){ const char *str; @@ -90,11 +89,12 @@ make_path(krb5_context context, struct tr_realm *r, N_("malloc: out of memory", "")); return ENOMEM; } - tmp->next = path; - path = tmp; - path->realm = strdup(p); - if(path->realm == NULL){ - r->next = path; /* XXX */ + tmp->next = r->next; + r->next = tmp; + tmp->realm = strdup(p); + if(tmp->realm == NULL){ + r->next = tmp->next; + free(tmp); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM;; @@ -104,10 +104,9 @@ make_path(krb5_context context, struct tr_realm *r, p = from + strlen(from); while(1){ while(p >= from && *p != '/') p--; - if(p == from) { - r->next = path; /* XXX */ + if(p == from) return KRB5KDC_ERR_POLICY; - } + if(strncmp(to, from, p - from) == 0) break; tmp = calloc(1, sizeof(*tmp)); @@ -116,24 +115,24 @@ make_path(krb5_context context, struct tr_realm *r, N_("malloc: out of memory", "")); return ENOMEM; } - tmp->next = path; - path = tmp; - path->realm = malloc(p - from + 1); - if(path->realm == NULL){ - r->next = path; /* XXX */ + tmp->next = r->next; + r->next = tmp; + tmp->realm = malloc(p - from + 1); + if(tmp->realm == NULL){ + r->next = tmp->next; + free(tmp); krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); return ENOMEM; } - memcpy(path->realm, from, p - from); - path->realm[p - from] = '\0'; + memcpy(tmp->realm, from, p - from); + tmp->realm[p - from] = '\0'; p--; } } else { krb5_clear_error_message (context); return KRB5KDC_ERR_POLICY; } - r->next = path; return 0; } @@ -359,17 +358,15 @@ krb5_domain_x500_decode(krb5_context context, return ret; /* remove empty components and count realms */ - q = &r; *num_realms = 0; - for(p = r; p; ){ - if(p->realm[0] == '\0'){ + for(q = &r; *q; ){ + if((*q)->realm[0] == '\0'){ + p = *q; + *q = (*q)->next; free(p->realm); - *q = p->next; free(p); - p = *q; }else{ - q = &p->next; - p = p->next; + q = &(*q)->next; (*num_realms)++; } } diff --git a/source4/heimdal/lib/krb5/warn.c b/source4/heimdal/lib/krb5/warn.c index 58fb73189e..b88b2004fb 100644 --- a/source4/heimdal/lib/krb5/warn.c +++ b/source4/heimdal/lib/krb5/warn.c @@ -65,13 +65,13 @@ _warnerr(krb5_context context, int do_errtext, err_str = krb5_get_error_message(context, code); if (err_str != NULL) { - *arg++ = err_str; + *arg = err_str; } else { err_msg = krb5_get_err_text(context, code); if (err_msg) - *arg++ = err_msg; + *arg = err_msg; else - *arg++ = "<unknown error>"; + *arg= "<unknown error>"; } } diff --git a/source4/heimdal/lib/roken/base64.c b/source4/heimdal/lib/roken/base64.c index 5e720eb6d4..bc74391b56 100644 --- a/source4/heimdal/lib/roken/base64.c +++ b/source4/heimdal/lib/roken/base64.c @@ -58,6 +58,11 @@ base64_encode(const void *data, int size, char **str) int c; const unsigned char *q; + if (size > INT_MAX/4 || size < 0) { + *str = NULL; + return -1; + } + p = s = (char *) malloc(size * 4 / 3 + 4); if (p == NULL) { *str = NULL; diff --git a/source4/heimdal/lib/roken/strpool.c b/source4/heimdal/lib/roken/strpool.c index dc56892144..642d335dec 100644 --- a/source4/heimdal/lib/roken/strpool.c +++ b/source4/heimdal/lib/roken/strpool.c @@ -100,7 +100,10 @@ rk_strpoolprintf(struct rk_strpool *p, const char *fmt, ...) char * ROKEN_LIB_FUNCTION rk_strpoolcollect(struct rk_strpool *p) { - char *str = p->str; + char *str; + if (p == NULL) + return strdup(""); + str = p->str; p->str = NULL; free(p); return str; diff --git a/source4/heimdal/lib/roken/vis.hin b/source4/heimdal/lib/roken/vis.hin index 06a250c6d8..737b2eb8f6 100644 --- a/source4/heimdal/lib/roken/vis.hin +++ b/source4/heimdal/lib/roken/vis.hin @@ -44,6 +44,8 @@ #include <sys/types.h> +#include <roken.h> + /* * to select alternate encoding format */ @@ -80,11 +82,8 @@ */ #define UNVIS_END 1 /* no more characters */ -#ifdef HAVE_SYS_CDEFS_H -#include <sys/cdefs.h> -#endif +ROKEN_CPP_START -__BEGIN_DECLS char * ROKEN_LIB_FUNCTION rk_vis(char *, int, int, int); char * ROKEN_LIB_FUNCTION @@ -103,7 +102,7 @@ int ROKEN_LIB_FUNCTION rk_strunvisx(char *, const char *, int); int ROKEN_LIB_FUNCTION rk_unvis(char *, int, int *, int); -__END_DECLS +ROKEN_CPP_END #undef vis #define vis(a,b,c,d) rk_vis(a,b,c,d) diff --git a/source4/heimdal_build/hdb-glue.c b/source4/heimdal_build/hdb-glue.c new file mode 100644 index 0000000000..c25a2f984e --- /dev/null +++ b/source4/heimdal_build/hdb-glue.c @@ -0,0 +1,35 @@ +/* + Unix SMB/CIFS implementation. + + provide glue functions between heimdal and samba + + Copyright (C) Andrew Bartlett <abartlet@samba.org> 2009 + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "includes.h" +#include "system/network.h" +#include "system/kerberos.h" +#include "lib/socket/netif.h" +#include "param/param.h" + +#include "heimdal/lib/hdb/hdb_locl.h" + +krb5_error_code +hdb_sqlite_create(krb5_context context, HDB **db, const char *argument) +{ + return EINVAL; +} + diff --git a/source4/heimdal_build/internal.mk b/source4/heimdal_build/internal.mk index 52281807b5..439f94aaf5 100644 --- a/source4/heimdal_build/internal.mk +++ b/source4/heimdal_build/internal.mk @@ -93,7 +93,8 @@ HEIMDAL_HDB_OBJ_FILES = \ $(heimdalsrcdir)/lib/hdb/keytab.o \ $(heimdalsrcdir)/lib/hdb/mkey.o \ $(heimdalsrcdir)/lib/hdb/ndbm.o \ - $(heimdalsrcdir)/lib/hdb/hdb_err.o + $(heimdalsrcdir)/lib/hdb/hdb_err.o \ + $(heimdalbuildsrcdir)/hdb-glue.o $(eval $(call heimdal_proto_header_template, \ $(heimdalsrcdir)/lib/hdb/hdb-protos.h, \ @@ -169,8 +170,10 @@ HEIMDAL_GSSAPI_KRB5_OBJ_FILES = \ $(heimdalsrcdir)/lib/gssapi/krb5/release_buffer.o \ $(heimdalsrcdir)/lib/gssapi/krb5/external.o \ $(heimdalsrcdir)/lib/gssapi/krb5/compat.o \ + $(heimdalsrcdir)/lib/gssapi/krb5/creds.o \ $(heimdalsrcdir)/lib/gssapi/krb5/acquire_cred.o \ $(heimdalsrcdir)/lib/gssapi/krb5/release_cred.o \ + $(heimdalsrcdir)/lib/gssapi/krb5/store_cred.o \ $(heimdalsrcdir)/lib/gssapi/krb5/set_cred_option.o \ $(heimdalsrcdir)/lib/gssapi/krb5/decapsulate.o \ $(heimdalsrcdir)/lib/gssapi/krb5/verify_mic.o \ @@ -197,6 +200,7 @@ HEIMDAL_GSSAPI_OBJ_FILES = \ $(heimdalsrcdir)/lib/gssapi/mech/gss_buffer_set.o \ $(heimdalsrcdir)/lib/gssapi/mech/gss_aeap.o \ $(heimdalsrcdir)/lib/gssapi/mech/gss_add_cred.o \ + $(heimdalsrcdir)/lib/gssapi/mech/gss_cred.o \ $(heimdalsrcdir)/lib/gssapi/mech/gss_add_oid_set_member.o \ $(heimdalsrcdir)/lib/gssapi/mech/gss_compare_name.o \ $(heimdalsrcdir)/lib/gssapi/mech/gss_release_oid_set.o \ |