From 533024be44861c8d2c8ba3232738c7d2dbbe2e4f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 27 Mar 2010 11:55:22 +1100 Subject: [PATCH] s4:heimdal: import lorikeet-heimdal-201003262338 (commit f4e0dc17709829235f057e0e100d34802d3929ff) --- source4/heimdal/kdc/default_config.c | 2 - source4/heimdal/kdc/headers.h | 2 +- source4/heimdal/kdc/kaserver.c | 6 +- source4/heimdal/kdc/kerberos5.c | 8 +- source4/heimdal/kdc/krb5tgs.c | 2 - source4/heimdal/kdc/log.c | 1 - source4/heimdal/kdc/misc.c | 2 - source4/heimdal/kdc/pkinit.c | 2 - source4/heimdal/kdc/windc.c | 2 - source4/heimdal/kuser/kinit.c | 112 +-------------------- source4/heimdal/lib/asn1/krb5.asn1 | 5 +- source4/heimdal/lib/gssapi/gssapi/gssapi.h | 10 +- .../lib/gssapi/mech/gss_accept_sec_context.c | 4 +- .../lib/gssapi/mech/gss_decapsulate_token.c | 4 +- .../lib/gssapi/mech/gss_encapsulate_token.c | 4 +- source4/heimdal/lib/gssapi/mech/gss_import_name.c | 25 +++++ .../heimdal/lib/gssapi/mech/gss_init_sec_context.c | 57 +++++++++++ source4/heimdal/lib/gssapi/mech/gss_release_name.c | 15 +++ source4/heimdal/lib/hcrypto/hmac.c | 4 +- source4/heimdal/lib/hcrypto/rand-unix.c | 12 ++- source4/heimdal/lib/hcrypto/rand.c | 19 +++- source4/heimdal/lib/hcrypto/randi.h | 1 + source4/heimdal/lib/hdb/hdb.h | 2 + source4/heimdal/lib/hdb/ndbm.c | 107 +++++++++++--------- source4/heimdal/lib/hx509/crypto.c | 2 +- source4/heimdal/lib/hx509/sel-lex.l | 4 + source4/heimdal/lib/krb5/constants.c | 1 + source4/heimdal/lib/krb5/context.c | 36 ++++--- source4/heimdal/lib/krb5/crypto.c | 54 ++++++++-- source4/heimdal/lib/krb5/get_cred.c | 4 +- source4/heimdal/lib/krb5/init_creds_pw.c | 12 +-- source4/heimdal/lib/krb5/principal.c | 14 +++ source4/heimdal/lib/krb5/rd_req.c | 2 +- source4/heimdal/lib/krb5/send_to_kdc.c | 2 +- source4/heimdal/lib/krb5/ticket.c | 12 ++- source4/heimdal/lib/roken/resolve.c | 36 ++++--- source4/heimdal/lib/roken/roken.h.in | 16 ++- source4/heimdal/lib/roken/socket.c | 21 ++++ source4/heimdal/lib/roken/strerror_r.c | 14 +-- 39 files changed, 381 insertions(+), 257 deletions(-) diff --git a/source4/heimdal/kdc/default_config.c b/source4/heimdal/kdc/default_config.c index b568522fa49..f5df4e0298c 100644 --- a/source4/heimdal/kdc/default_config.c +++ b/source4/heimdal/kdc/default_config.c @@ -37,8 +37,6 @@ #include #include -RCSID("$Id$"); - krb5_error_code krb5_kdc_get_config(krb5_context context, krb5_kdc_configuration **config) { diff --git a/source4/heimdal/kdc/headers.h b/source4/heimdal/kdc/headers.h index 1eb3ddedcd8..aced5ce6170 100644 --- a/source4/heimdal/kdc/headers.h +++ b/source4/heimdal/kdc/headers.h @@ -107,7 +107,7 @@ #include #undef ALLOC -#define ALLOC(X) ((X) = malloc(sizeof(*(X)))) +#define ALLOC(X) ((X) = calloc(1, sizeof(*(X)))) #undef ALLOC_SEQ #define ALLOC_SEQ(X, N) do { (X)->len = (N); \ (X)->val = calloc((X)->len, sizeof(*(X)->val)); } while(0) diff --git a/source4/heimdal/kdc/kaserver.c b/source4/heimdal/kdc/kaserver.c index 69b5bb1d6e9..827205a8056 100644 --- a/source4/heimdal/kdc/kaserver.c +++ b/source4/heimdal/kdc/kaserver.c @@ -738,9 +738,11 @@ do_getticket (krb5_context context, config->v4_realm, &sname, &sinstance, &ad); if (ret) { + const char *msg = krb5_get_error_message(context, ret); kdc_log(context, config, 0, - "kaserver: decomp failed for %s.%s with %d", - sname, sinstance, ret); + "kaserver: decomp failed for %s.%s with %s %d", + msg, sname, sinstance, ret); + krb5_free_error_message(context, msg); make_error_reply (hdr, KABADTICKET, reply); goto out; } diff --git a/source4/heimdal/kdc/kerberos5.c b/source4/heimdal/kdc/kerberos5.c index 87162d5f98e..c3e94757e38 100644 --- a/source4/heimdal/kdc/kerberos5.c +++ b/source4/heimdal/kdc/kerberos5.c @@ -33,8 +33,6 @@ #include "kdc_locl.h" -RCSID("$Id$"); - #define MAX_TIME ((time_t)((1U << 31) - 1)) void @@ -1425,6 +1423,7 @@ _kdc_as_rep(krb5_context context, if(f.renew || f.validate || f.proxy || f.forwarded || f.enc_tkt_in_skey || (f.request_anonymous && !config->allow_anonymous)) { ret = KRB5KDC_ERR_BADOPTION; + e_text = "Bad KDC options"; kdc_log(context, config, 0, "Bad KDC options -- %s", client_name); goto out; } @@ -1454,6 +1453,7 @@ _kdc_as_rep(krb5_context context, if(client->entry.flags.forwardable && server->entry.flags.forwardable) et.flags.forwardable = f.forwardable; else if (f.forwardable) { + e_text = "Ticket may not be forwardable"; ret = KRB5KDC_ERR_POLICY; kdc_log(context, config, 0, "Ticket may not be forwardable -- %s", client_name); @@ -1462,6 +1462,7 @@ _kdc_as_rep(krb5_context context, if(client->entry.flags.proxiable && server->entry.flags.proxiable) et.flags.proxiable = f.proxiable; else if (f.proxiable) { + e_text = "Ticket may not be proxiable"; ret = KRB5KDC_ERR_POLICY; kdc_log(context, config, 0, "Ticket may not be proxiable -- %s", client_name); @@ -1470,6 +1471,7 @@ _kdc_as_rep(krb5_context context, if(client->entry.flags.postdate && server->entry.flags.postdate) et.flags.may_postdate = f.allow_postdate; else if (f.allow_postdate){ + e_text = "Ticket may not be postdate"; ret = KRB5KDC_ERR_POLICY; kdc_log(context, config, 0, "Ticket may not be postdatable -- %s", client_name); @@ -1478,6 +1480,7 @@ _kdc_as_rep(krb5_context context, /* check for valid set of addresses */ if(!_kdc_check_addresses(context, config, b->addresses, from_addr)) { + e_text = "Bad address list in requested"; ret = KRB5KRB_AP_ERR_BADADDR; kdc_log(context, config, 0, "Bad address list requested -- %s", client_name); @@ -1630,6 +1633,7 @@ _kdc_as_rep(krb5_context context, &et); if (ret) goto out; + } else #endif { diff --git a/source4/heimdal/kdc/krb5tgs.c b/source4/heimdal/kdc/krb5tgs.c index b6f9c865bbd..53c0a589ba9 100644 --- a/source4/heimdal/kdc/krb5tgs.c +++ b/source4/heimdal/kdc/krb5tgs.c @@ -33,8 +33,6 @@ #include "kdc_locl.h" -RCSID("$Id$"); - /* * return the realm of a krbtgt-ticket or NULL */ diff --git a/source4/heimdal/kdc/log.c b/source4/heimdal/kdc/log.c index 06e64df840a..6657aca5cb4 100644 --- a/source4/heimdal/kdc/log.c +++ b/source4/heimdal/kdc/log.c @@ -34,7 +34,6 @@ */ #include "kdc_locl.h" -RCSID("$Id$"); void kdc_openlog(krb5_context context, diff --git a/source4/heimdal/kdc/misc.c b/source4/heimdal/kdc/misc.c index 9a3f2546403..39f91dcf10f 100644 --- a/source4/heimdal/kdc/misc.c +++ b/source4/heimdal/kdc/misc.c @@ -33,8 +33,6 @@ #include "kdc_locl.h" -RCSID("$Id$"); - struct timeval _kdc_now; krb5_error_code diff --git a/source4/heimdal/kdc/pkinit.c b/source4/heimdal/kdc/pkinit.c index 099d3ebe7df..4405bf4f194 100644 --- a/source4/heimdal/kdc/pkinit.c +++ b/source4/heimdal/kdc/pkinit.c @@ -35,8 +35,6 @@ #include "kdc_locl.h" -RCSID("$Id$"); - #ifdef PKINIT #include diff --git a/source4/heimdal/kdc/windc.c b/source4/heimdal/kdc/windc.c index 0ef9cdb7aba..524bc90d90c 100644 --- a/source4/heimdal/kdc/windc.c +++ b/source4/heimdal/kdc/windc.c @@ -33,8 +33,6 @@ #include "kdc_locl.h" -RCSID("$Id$"); - static krb5plugin_windc_ftable *windcft; static void *windcctx; diff --git a/source4/heimdal/kuser/kinit.c b/source4/heimdal/kuser/kinit.c index 4e9e6ac3d7e..e6201fbbc03 100644 --- a/source4/heimdal/kuser/kinit.c +++ b/source4/heimdal/kuser/kinit.c @@ -39,10 +39,6 @@ #include #endif -#ifndef HEIMDAL_SMALLER -#include "krb5-v4compat.h" -#endif - struct krb5_dh_moduli; struct AlgorithmIdentifier; struct _krb5_krb_auth_data; @@ -74,11 +70,6 @@ struct getarg_strings etype_str; int use_keytab = 0; char *keytab_str = NULL; int do_afslog = -1; -#ifndef HEIMDAL_SMALLER -int get_v4_tgt = -1; -int convert_524 = 0; -static char *krb4_cc_name; -#endif int fcache_version; char *password_file = NULL; char *pk_user_id = NULL; @@ -105,14 +96,11 @@ static struct getargs args[] = { * P: ~p * C: v4 cache name? * 5: + * + * old flags + * 4: + * 9: */ -#ifndef HEIMDAL_SMALLER - { "524init", '4', arg_flag, &get_v4_tgt, - NP_("obtain version 4 TGT", "") }, - - { "524convert", '9', arg_flag, &convert_524, - NP_("only convert ticket to version 4", "") }, -#endif { "afslog", 0 , arg_flag, &do_afslog, NP_("obtain afs tokens", "") }, @@ -239,58 +227,6 @@ get_server(krb5_context context, KRB5_TGS_NAME, realm, NULL); } -#ifndef HEIMDAL_SMALLER - -static krb5_error_code -do_524init(krb5_context context, krb5_ccache ccache, - krb5_creds *creds, const char *server) -{ - krb5_error_code ret; - - struct credentials c; - krb5_creds in_creds, *real_creds; - - if(creds != NULL) - real_creds = creds; - else { - krb5_principal client; - ret = krb5_cc_get_principal(context, ccache, &client); - if (ret) { - krb5_warn(context, ret, "524init: can't get client principal"); - return ret; - } - memset(&in_creds, 0, sizeof(in_creds)); - ret = get_server(context, client, server, &in_creds.server); - if(ret) { - krb5_warn(context, ret, "524init: can't get server principal"); - krb5_free_principal(context, client); - return ret; - } - in_creds.client = client; - ret = krb5_get_credentials(context, 0, ccache, &in_creds, &real_creds); - krb5_free_principal(context, client); - krb5_free_principal(context, in_creds.server); - if(ret) - return ret; - } - ret = krb524_convert_creds_kdc_ccache(context, ccache, real_creds, &c); - if(ret) - krb5_warn(context, ret, "converting creds"); - else { - krb5_error_code tret = _krb5_krb_tf_setup(context, &c, NULL, 0); - if(tret) - krb5_warn(context, tret, "saving v4 creds"); - } - - if(creds == NULL) - krb5_free_creds(context, real_creds); - memset(&c, 0, sizeof(c)); - - return ret; -} - -#endif - static int renew_validate(krb5_context context, int renew, @@ -370,10 +306,6 @@ renew_validate(krb5_context context, if(ret == 0 && server == NULL) { /* only do this if it's a general renew-my-tgt request */ -#ifndef HEIMDAL_SMALLER - if(get_v4_tgt) - do_524init(context, cache, out, NULL); -#endif #ifndef NO_AFS if(do_afslog && k_hasafs()) krb5_afslog(context, cache, NULL, NULL); @@ -782,10 +714,6 @@ renew_func(void *ptr) get_new_tickets(ctx->context, ctx->principal, ctx->ccache, ctx->ticket_life, 0); -#ifndef HEIMDAL_SMALLER - if(get_v4_tgt || convert_524) - do_524init(ctx->context, ctx->ccache, NULL, server_str); -#endif #ifndef NO_AFS if(do_afslog && k_hasafs()) krb5_afslog(ctx->context, ctx->ccache, NULL, NULL); @@ -875,12 +803,6 @@ main (int argc, char **argv) krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), "renewable", FALSE, &renewable_flag); -#ifndef HEIMDAL_SMALLER - if(get_v4_tgt == -1) - krb5_appdefault_boolean(context, "kinit", - krb5_principal_get_realm(context, principal), - "krb4_get_tickets", FALSE, &get_v4_tgt); -#endif if(do_afslog == -1) krb5_appdefault_boolean(context, "kinit", krb5_principal_get_realm(context, principal), @@ -898,20 +820,6 @@ main (int argc, char **argv) krb5_cc_get_type(context, ccache), krb5_cc_get_name(context, ccache)); setenv("KRB5CCNAME", s, 1); -#ifndef HEIMDAL_SMALLER - if (get_v4_tgt) { - int fd; - if (asprintf(&krb4_cc_name, "%s_XXXXXX", TKT_ROOT) < 0) - krb5_errx(context, 1, "out of memory"); - if((fd = mkstemp(krb4_cc_name)) >= 0) { - close(fd); - setenv("KRBTKFILE", krb4_cc_name, 1); - } else { - free(krb4_cc_name); - krb4_cc_name = NULL; - } - } -#endif } else { ret = krb5_cc_cache_match(context, principal, &ccache); if (ret) { @@ -974,15 +882,8 @@ main (int argc, char **argv) exit(ret != 0); } -#ifndef HEIMDAL_SMALLER - if(!convert_524) -#endif - get_new_tickets(context, principal, ccache, ticket_life, 1); + get_new_tickets(context, principal, ccache, ticket_life, 1); -#ifndef HEIMDAL_SMALLER - if(get_v4_tgt || convert_524) - do_524init(context, ccache, NULL, server_str); -#endif #ifndef NO_AFS if(do_afslog && k_hasafs()) krb5_afslog(context, ccache, NULL, NULL); @@ -1008,9 +909,6 @@ main (int argc, char **argv) krb5_warnx(context, N_("command not found: %s", ""), argv[1]); krb5_cc_destroy(context, ccache); -#ifndef HEIMDAL_SMALLER - _krb5_krb_dest_tkt(context, krb4_cc_name); -#endif #ifndef NO_AFS if(k_hasafs()) k_unlog(); diff --git a/source4/heimdal/lib/asn1/krb5.asn1 b/source4/heimdal/lib/asn1/krb5.asn1 index ed663fcf5fb..b9a566de7b4 100644 --- a/source4/heimdal/lib/asn1/krb5.asn1 +++ b/source4/heimdal/lib/asn1/krb5.asn1 @@ -190,8 +190,9 @@ AUTHDATA-TYPE ::= INTEGER { KRB5-AUTHDATA-OSF-DCE-PKI-CERTID(66), KRB5-AUTHDATA-WIN2K-PAC(128), KRB5-AUTHDATA-GSS-API-ETYPE-NEGOTIATION(129), -- Authenticator only - KRB5-AUTHDATA-SIGNTICKET-OLD(-17), - KRB5-AUTHDATA-SIGNTICKET(142) + KRB5-AUTHDATA-SIGNTICKET-OLDER(-17), + KRB5-AUTHDATA-SIGNTICKET-OLD(142), + KRB5-AUTHDATA-SIGNTICKET(512) } -- checksumtypes diff --git a/source4/heimdal/lib/gssapi/gssapi/gssapi.h b/source4/heimdal/lib/gssapi/gssapi/gssapi.h index 730737a46a8..3f217d38cb8 100644 --- a/source4/heimdal/lib/gssapi/gssapi/gssapi.h +++ b/source4/heimdal/lib/gssapi/gssapi/gssapi.h @@ -862,18 +862,18 @@ OM_uint32 GSSAPI_LIB_FUNCTION GSSAPI_DEPRECATED gss_unseal int * /*qop_state*/ ); -/* +/** * */ OM_uint32 GSSAPI_LIB_FUNCTION -gss_encapsulate_token(gss_buffer_t /* input_token */, - gss_OID /* oid */, +gss_encapsulate_token(const gss_buffer_t /* input_token */, + const gss_OID /* oid */, gss_buffer_t /* output_token */); OM_uint32 GSSAPI_LIB_FUNCTION -gss_decapsulate_token(gss_buffer_t /* input_token */, - gss_OID /* oid */, +gss_decapsulate_token(const gss_buffer_t /* input_token */, + const gss_OID /* oid */, gss_buffer_t /* output_token */); diff --git a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c index 1529ab1137f..5775db837b4 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_accept_sec_context.c @@ -263,8 +263,8 @@ OM_uint32 gss_accept_sec_context(OM_uint32 *minor_status, if (mech_ret_flags & GSS_C_DELEG_FLAG) { if (!delegated_cred_handle) { m->gm_release_cred(minor_status, &delegated_mc); - if (ret_flags) - *ret_flags &= ~GSS_C_DELEG_FLAG; + mech_ret_flags &= + ~(GSS_C_DELEG_FLAG|GSS_C_DELEG_POLICY_FLAG); } else if (gss_oid_equal(mech_ret_type, &m->gm_mech_oid) == 0) { /* * If the returned mech_type is not the same diff --git a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c index 8db0832d862..95a6c68445f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_decapsulate_token.c @@ -34,8 +34,8 @@ #include "mech_locl.h" OM_uint32 GSSAPI_LIB_FUNCTION -gss_decapsulate_token(gss_buffer_t input_token, - gss_OID oid, +gss_decapsulate_token(const gss_buffer_t input_token, + const gss_OID oid, gss_buffer_t output_token) { GSSAPIContextToken ct; diff --git a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c index e14b00f9ced..7a3e165364f 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c +++ b/source4/heimdal/lib/gssapi/mech/gss_encapsulate_token.c @@ -34,8 +34,8 @@ #include "mech_locl.h" OM_uint32 GSSAPI_LIB_FUNCTION -gss_encapsulate_token(gss_buffer_t input_token, - gss_OID oid, +gss_encapsulate_token(const gss_buffer_t input_token, + const gss_OID oid, gss_buffer_t output_token) { GSSAPIContextToken ct; diff --git a/source4/heimdal/lib/gssapi/mech/gss_import_name.c b/source4/heimdal/lib/gssapi/mech/gss_import_name.c index 19ab75a84c8..6ae2302abd9 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_import_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_import_name.c @@ -138,6 +138,31 @@ _gss_import_export_name(OM_uint32 *minor_status, return (GSS_S_COMPLETE); } +/** + * Import a name internal or mechanism name + * + * Type of name and their format: + * - GSS_C_NO_OID + * - GSS_C_NT_USER_NAME + * - GSS_C_NT_HOSTBASED_SERVICE + * - GSS_C_NT_EXPORT_NAME + * - GSS_C_NT_ANONYMOUS + * - GSS_KRB5_NT_PRINCIPAL_NAME + * + * For more information about @ref internalVSmechname. + * + * @param minor_status minor status code + * @param input_name_buffer import name buffer + * @param input_name_type type of the import name buffer + * @param output_name the resulting type, release with + * gss_release_name(), independent of input_name + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + OM_uint32 GSSAPI_LIB_FUNCTION gss_import_name(OM_uint32 *minor_status, const gss_buffer_t input_name_buffer, diff --git a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c index dfebe261091..1bcc6393452 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c +++ b/source4/heimdal/lib/gssapi/mech/gss_init_sec_context.c @@ -44,6 +44,63 @@ _gss_mech_cred_find(gss_cred_id_t cred_handle, gss_OID mech_type) return GSS_C_NO_CREDENTIAL; } +/** + * As the initiator build a context with an acceptor. + * + * Returns in the major + * - GSS_S_COMPLETE - if the context if build + * - GSS_S_CONTINUE_NEEDED - if the caller needs to continue another + * round of gss_i nit_sec_context + * - error code - any other error code + * + * @param minor_status minor status code. + * + * @param context_handle a pointer to a context handle, will be + * returned as long as there is not an error. + * + * @param target_name the target name of acceptor, created using + * gss_import_name(). The name is can be of any name types the + * mechanism supports, check supported name types with + * gss_inquire_names_for_mech(). + * + * @param input_mech_type mechanism type to use, if GSS_C_NO_OID is + * used, Kerberos (GSS_KRB5_MECHANISM) will be tried. Other + * available mechanism are listed in the @ref gssapi_mechs_intro + * section. + * + * @param req_flags flags using when building the context, see @ref + * gssapi_context_ flags + * + * @param time_req time requested this context should be valid in + * seconds, common used value is GSS_C_INDEFINITE + * + * @param input_chan_bindings Channel bindings used, if not exepected + * otherwise, used GSS_C_NO_CHANNEL_BINDINGS + * + * @param input_token input token sent from the acceptor, for the + * initial packet the buffer of { NULL, 0 } should be used. + * + * @param actual_mech_type the actual mech used, MUST NOT be freed + * since it pointing to static memory. + * + * @param output_token if there is an output token, regardless of + * complete, continue_needed, or error it should be sent to the + * acceptor + * + * @param ret_flags return what flags was negotitated, caller should + * check if they are accetable. For example, if + * GSS_C_MUTUAL_FLAG was negotiated with the acceptor or not. + * + * @param time_rec amount of time this context is valid for + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ + + + OM_uint32 GSSAPI_LIB_FUNCTION gss_init_sec_context(OM_uint32 * minor_status, const gss_cred_id_t initiator_cred_handle, diff --git a/source4/heimdal/lib/gssapi/mech/gss_release_name.c b/source4/heimdal/lib/gssapi/mech/gss_release_name.c index 84553ee05d0..47786725acc 100644 --- a/source4/heimdal/lib/gssapi/mech/gss_release_name.c +++ b/source4/heimdal/lib/gssapi/mech/gss_release_name.c @@ -28,6 +28,21 @@ #include "mech_locl.h" +/** + * Free a name + * + * import_name can point to NULL or be NULL, or a pointer to a + * gss_name_t structure. If it was a pointer to gss_name_t, the + * pointer will be set to NULL on success and failure. + * + * @param minor_status minor status code + * @param input_name name to free + * + * @returns a gss_error code, see gss_display_status() about printing + * the error code. + * + * @ingroup gssapi + */ OM_uint32 GSSAPI_LIB_FUNCTION gss_release_name(OM_uint32 *minor_status, gss_name_t *input_name) diff --git a/source4/heimdal/lib/hcrypto/hmac.c b/source4/heimdal/lib/hcrypto/hmac.c index dcd836d0be3..d11bd987698 100644 --- a/source4/heimdal/lib/hcrypto/hmac.c +++ b/source4/heimdal/lib/hcrypto/hmac.c @@ -52,12 +52,12 @@ HMAC_CTX_cleanup(HMAC_CTX *ctx) ctx->buf = NULL; } if (ctx->opad) { - memset(ctx->ipad, 0, ctx->key_length); + memset(ctx->opad, 0, EVP_MD_block_size(ctx->md)); free(ctx->opad); ctx->opad = NULL; } if (ctx->ipad) { - memset(ctx->ipad, 0, ctx->key_length); + memset(ctx->ipad, 0, EVP_MD_block_size(ctx->md)); free(ctx->ipad); ctx->ipad = NULL; } diff --git a/source4/heimdal/lib/hcrypto/rand-unix.c b/source4/heimdal/lib/hcrypto/rand-unix.c index 4c1f33da595..63dc97fbfa7 100644 --- a/source4/heimdal/lib/hcrypto/rand-unix.c +++ b/source4/heimdal/lib/hcrypto/rand-unix.c @@ -46,8 +46,8 @@ * Unix /dev/random */ -static int -get_device_fd(int flags) +int +_hc_unix_device_fd(int flags, char **fn) { static const char *rnd_devices[] = { "/dev/urandom", @@ -61,6 +61,8 @@ get_device_fd(int flags) for(p = rnd_devices; *p; p++) { int fd = open(*p, flags | O_NDELAY); if(fd >= 0) { + if (fn) + *fn = *p; rk_cloexec(fd); return fd; } @@ -76,7 +78,7 @@ unix_seed(const void *indata, int size) if (size <= 0) return; - fd = get_device_fd(O_WRONLY); + fd = _hc_unix_device_fd(O_WRONLY, NULL); if (fd < 0) return; @@ -97,7 +99,7 @@ unix_bytes(unsigned char *outdata, int size) else if (size == 0) return 1; - fd = get_device_fd(O_RDONLY); + fd = _hc_unix_device_fd(O_RDONLY, NULL); if (fd < 0) return 0; @@ -139,7 +141,7 @@ unix_status(void) { int fd; - fd = get_device_fd(O_RDONLY); + fd = _hc_unix_device_fd(O_RDONLY, NULL); if (fd < 0) return 0; close(fd); diff --git a/source4/heimdal/lib/hcrypto/rand.c b/source4/heimdal/lib/hcrypto/rand.c index 9f0438a34e8..d360ffcab4c 100644 --- a/source4/heimdal/lib/hcrypto/rand.c +++ b/source4/heimdal/lib/hcrypto/rand.c @@ -342,23 +342,32 @@ RAND_write_file(const char *filename) const char * RAND_file_name(char *filename, size_t size) { - const char *e = NULL; + char *e = NULL; int pathp = 0, ret; if (!issuid()) { e = getenv("RANDFILE"); - if (e == NULL) { + if (e == NULL) e = getenv("HOME"); - if (e) - pathp = 1; - } + if (e) + pathp = 1; } /* * Here we really want to call getpwuid(getuid()) but this will * cause recursive lookups if the nss library uses * gssapi/krb5/hcrypto to authenticate to the ldap servers. + * + * So at least return the unix /dev/random if we have one */ +#ifndef _WIN32 + if (e == NULL) { + int fd; + fd = _hc_unix_device_fd(O_RDONLY, &e); + if (fd >= 0) + close(fd); + } +#endif if (e == NULL) return NULL; diff --git a/source4/heimdal/lib/hcrypto/randi.h b/source4/heimdal/lib/hcrypto/randi.h index c6c617af22a..a6d921413a3 100644 --- a/source4/heimdal/lib/hcrypto/randi.h +++ b/source4/heimdal/lib/hcrypto/randi.h @@ -45,5 +45,6 @@ extern const RAND_METHOD hc_rand_timer_method; extern const RAND_METHOD hc_rand_w32crypto_method; const RAND_METHOD * RAND_timer_method(void); +int _hc_unix_device_fd(int, char **); #endif /* _HEIM_RANDI_H */ diff --git a/source4/heimdal/lib/hdb/hdb.h b/source4/heimdal/lib/hdb/hdb.h index 91b67537224..d1185551215 100644 --- a/source4/heimdal/lib/hdb/hdb.h +++ b/source4/heimdal/lib/hdb/hdb.h @@ -158,6 +158,8 @@ typedef struct HDB{ krb5_error_code (*hdb_unlock)(krb5_context, struct HDB*); /** * Rename the data base. + * + * Assume that the database is not hdb_open'ed and not locked. */ krb5_error_code (*hdb_rename)(krb5_context, struct HDB*, const char*); /** diff --git a/source4/heimdal/lib/hdb/ndbm.c b/source4/heimdal/lib/hdb/ndbm.c index d97a98ed6b5..bad3c497428 100644 --- a/source4/heimdal/lib/hdb/ndbm.c +++ b/source4/heimdal/lib/hdb/ndbm.c @@ -131,40 +131,59 @@ NDBM_nextkey(krb5_context context, HDB *db, unsigned flags,hdb_entry_ex *entry) } static krb5_error_code -NDBM_rename(krb5_context context, HDB *db, const char *new_name) +open_lock_file(krb5_context context, const char *db_name, int *fd) { - /* XXX this function will break */ - struct ndbm_db *d = db->hdb_db; + char *lock_file; + + /* lock old and new databases */ + asprintf(&lock_file, "%s.lock", db_name); + if(lock_file == NULL) { + krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); + return ENOMEM; + } + + *fd = open(lock_file, O_RDWR | O_CREAT, 0600); + free(lock_file); + if(*fd < 0) { + int ret = errno; + krb5_set_error_message(context, ret, "open(%s): %s", lock_file, + strerror(ret)); + return ret; + } + return 0; +} + +static krb5_error_code +NDBM_rename(krb5_context context, HDB *db, const char *new_name) +{ int ret; char *old_dir, *old_pag, *new_dir, *new_pag; - char *new_lock; - int lock_fd; + int old_lock_fd, new_lock_fd; /* lock old and new databases */ - ret = db->hdb_lock(context, db, HDB_WLOCK); - if(ret) + ret = open_lock_file(context, db->hdb_name, &old_lock_fd); + if (ret) + return ret; + + ret = hdb_lock(old_lock_fd, HDB_WLOCK); + if(ret) { + close(old_lock_fd); return ret; - asprintf(&new_lock, "%s.lock", new_name); - if(new_lock == NULL) { - db->hdb_unlock(context, db); - krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); - return ENOMEM; } - lock_fd = open(new_lock, O_RDWR | O_CREAT, 0600); - if(lock_fd < 0) { - ret = errno; - db->hdb_unlock(context, db); - krb5_set_error_message(context, ret, "open(%s): %s", new_lock, - strerror(ret)); - free(new_lock); + + ret = open_lock_file(context, new_name, &new_lock_fd); + if (ret) { + hdb_unlock(old_lock_fd); + close(old_lock_fd); return ret; } - free(new_lock); - ret = hdb_lock(lock_fd, HDB_WLOCK); + + ret = hdb_lock(new_lock_fd, HDB_WLOCK); if(ret) { - db->hdb_unlock(context, db); - close(lock_fd); + hdb_unlock(old_lock_fd); + close(old_lock_fd); + close(new_lock_fd); return ret; } @@ -174,22 +193,25 @@ NDBM_rename(krb5_context context, HDB *db, const char *new_name) asprintf(&new_pag, "%s.pag", new_name); ret = rename(old_dir, new_dir) || rename(old_pag, new_pag); + if (ret) { + ret = errno; + if (ret == 0) + ret = EPERM; + krb5_set_error_message(context, ret, "rename: %s", strerror(ret)); + } + free(old_dir); free(old_pag); free(new_dir); free(new_pag); - hdb_unlock(lock_fd); - db->hdb_unlock(context, db); - if(ret) { - ret = errno; - close(lock_fd); - krb5_set_error_message(context, ret, "rename: %s", strerror(ret)); - return ret; - } + hdb_unlock(new_lock_fd); + hdb_unlock(old_lock_fd); + close(new_lock_fd); + close(old_lock_fd); - close(d->lock_fd); - d->lock_fd = lock_fd; + if(ret) + return ret; free(db->hdb_name); db->hdb_name = strdup(new_name); @@ -277,38 +299,31 @@ NDBM_open(krb5_context context, HDB *db, int flags, mode_t mode) { krb5_error_code ret; struct ndbm_db *d = malloc(sizeof(*d)); - char *lock_file; if(d == NULL) { krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); return ENOMEM; } - asprintf(&lock_file, "%s.lock", (char*)db->hdb_name); - if(lock_file == NULL) { - free(d); - krb5_set_error_message(context, ENOMEM, "malloc: out of memory"); - return ENOMEM; - } + d->db = dbm_open((char*)db->hdb_name, flags, mode); if(d->db == NULL){ ret = errno; free(d); - free(lock_file); krb5_set_error_message(context, ret, "dbm_open(%s): %s", db->hdb_name, strerror(ret)); return ret; } - d->lock_fd = open(lock_file, O_RDWR | O_CREAT, 0600); - if(d->lock_fd < 0){ + + ret = open_lock_file(context, db->hdb_name, &d->lock_fd); + if (ret) { ret = errno; dbm_close(d->db); free(d); - krb5_set_error_message(context, ret, "open(%s): %s", lock_file, + krb5_set_error_message(context, ret, "open(lock file): %s", strerror(ret)); - free(lock_file); return ret; } - free(lock_file); + db->hdb_db = d; if((flags & O_ACCMODE) == O_RDONLY) ret = hdb_check_db_format(context, db); diff --git a/source4/heimdal/lib/hx509/crypto.c b/source4/heimdal/lib/hx509/crypto.c index bee64c145f6..77be4413ac9 100644 --- a/source4/heimdal/lib/hx509/crypto.c +++ b/source4/heimdal/lib/hx509/crypto.c @@ -740,7 +740,7 @@ rsa_create_signature(hx509_context context, if (ret <= 0) { ret = HX509_CMS_FAILED_CREATE_SIGATURE; hx509_set_error_string(context, 0, ret, - "RSA private decrypt failed: %d", ret); + "RSA private encrypt failed: %d", ret); return ret; } if (ret > sig->length) diff --git a/source4/heimdal/lib/hx509/sel-lex.l b/source4/heimdal/lib/hx509/sel-lex.l index e9bbbc6087d..4c9396750a3 100644 --- a/source4/heimdal/lib/hx509/sel-lex.l +++ b/source4/heimdal/lib/hx509/sel-lex.l @@ -53,6 +53,10 @@ static int lex_input(char *, int); struct hx_expr_input _hx509_expr_input; +#ifndef YY_NULL +#define YY_NULL 0 +#endif + #define YY_NO_UNPUT 1 #undef YY_INPUT diff --git a/source4/heimdal/lib/krb5/constants.c b/source4/heimdal/lib/krb5/constants.c index b85f0cf6070..6223fb5d6b4 100644 --- a/source4/heimdal/lib/krb5/constants.c +++ b/source4/heimdal/lib/krb5/constants.c @@ -42,6 +42,7 @@ KRB5_LIB_VARIABLE const char *krb5_config_file = "~/Library/Preferences/edu.mit.Kerberos:" "/Library/Preferences/edu.mit.Kerberos:" #endif /* __APPLE__ */ +"~/.krb5/config:" SYSCONFDIR "/krb5.conf" #ifndef _WIN32 ":/etc/krb5.conf" diff --git a/source4/heimdal/lib/krb5/context.c b/source4/heimdal/lib/krb5/context.c index dff7a700c4f..adcbb703ee1 100644 --- a/source4/heimdal/lib/krb5/context.c +++ b/source4/heimdal/lib/krb5/context.c @@ -535,7 +535,8 @@ krb5_free_context(krb5_context context) krb5_set_send_to_kdc_func(context, NULL, NULL); #ifdef PKINIT - hx509_context_free(&context->hx509ctx); + if (context->hx509ctx) + hx509_context_free(&context->hx509ctx); #endif HEIMDAL_MUTEX_destroy(context->mutex); @@ -824,23 +825,33 @@ KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_set_default_in_tkt_etypes(krb5_context context, const krb5_enctype *etypes) { + krb5_error_code ret; krb5_enctype *p = NULL; - int i; + unsigned int n, m; if(etypes) { - for (i = 0; etypes[i]; ++i) { - krb5_error_code ret; - ret = krb5_enctype_valid(context, etypes[i]); - if (ret) - return ret; - } - ++i; - ALLOC(p, i); + for (n = 0; etypes[n]; n++) + ; + n++; + ALLOC(p, n); if(!p) { - krb5_set_error_message (context, ENOMEM, N_("malloc: out of memory", "")); + krb5_set_error_message (context, ENOMEM, + N_("malloc: out of memory", "")); return ENOMEM; } - memmove(p, etypes, i * sizeof(krb5_enctype)); + for (n = 0, m = 0; etypes[n]; n++) { + ret = krb5_enctype_valid(context, etypes[n]); + if (ret) + continue; + p[m++] = etypes[n]; + } + p[m] = ETYPE_NULL; + if (m == 0) { + free(p); + krb5_set_error_message (context, KRB5_PROG_ETYPE_NOSUPP, + N_("no valid enctype set", "")); + return KRB5_PROG_ETYPE_NOSUPP; + } } if(context->etypes) free(context->etypes); @@ -1375,6 +1386,7 @@ _krb5_homedir_access(krb5_context context) * @param allow allow if TRUE home directory * @return the old value * + * @ingroup krb5 */ krb5_boolean diff --git a/source4/heimdal/lib/krb5/crypto.c b/source4/heimdal/lib/krb5/crypto.c index 5906d43f5f5..ed8765542c0 100644 --- a/source4/heimdal/lib/krb5/crypto.c +++ b/source4/heimdal/lib/krb5/crypto.c @@ -67,6 +67,7 @@ struct krb5_crypto_data { #define F_PSEUDO 16 /* not a real protocol type */ #define F_SPECIAL 32 /* backwards */ #define F_DISABLED 64 /* enctype/checksum disabled */ +#define F_WEAK 128 /* enctype is considered weak */ struct salt_type { krb5_salttype type; @@ -2612,7 +2613,7 @@ static struct encryption_type enctype_des_cbc_crc = { &keytype_des, &checksum_crc32, NULL, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_key_ivec, 0, NULL @@ -2626,7 +2627,7 @@ static struct encryption_type enctype_des_cbc_md4 = { &keytype_des, &checksum_rsa_md4, &checksum_rsa_md4_des, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2640,7 +2641,7 @@ static struct encryption_type enctype_des_cbc_md5 = { &keytype_des, &checksum_rsa_md5, &checksum_rsa_md5_des, - F_DISABLED, + F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2654,7 +2655,7 @@ static struct encryption_type enctype_des_cbc_none = { &keytype_des, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, evp_des_encrypt_null_ivec, 0, NULL @@ -2668,7 +2669,7 @@ static struct encryption_type enctype_des_cfb64_none = { &keytype_des_old, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, DES_CFB64_encrypt_null_ivec, 0, NULL @@ -2682,7 +2683,7 @@ static struct encryption_type enctype_des_pcbc_none = { &keytype_des_old, &checksum_none, NULL, - F_PSEUDO|F_DISABLED, + F_PSEUDO|F_DISABLED|F_WEAK, DES_PCBC_encrypt_key_ivec, 0, NULL @@ -3143,8 +3144,14 @@ decrypt_internal(krb5_context context, krb5_clear_error_message(context); return KRB5_BAD_MSIZE; } - checksum_sz = CHECKSUMSIZE(et->checksum); + if (len < checksum_sz + et->confoundersize) { + krb5_set_error_message(context, KRB5_BAD_MSIZE, + N_("Encrypted data shorter then " + "checksum + confunder", "")); + return KRB5_BAD_MSIZE; + } + p = malloc(len); if(len != 0 && p == NULL) { krb5_set_error_message(context, ENOMEM, N_("malloc: out of memory", "")); @@ -3206,6 +3213,12 @@ decrypt_internal_special(krb5_context context, krb5_clear_error_message(context); return KRB5_BAD_MSIZE; } + if (len < cksum_sz + et->confoundersize) { + krb5_set_error_message(context, KRB5_BAD_MSIZE, + N_("Encrypted data shorter then " + "checksum + confunder", "")); + return KRB5_BAD_MSIZE; + } p = malloc (len); if (p == NULL) { @@ -4402,6 +4415,33 @@ krb5_enctype_enable(krb5_context context, return 0; } +/** + * Enable or disable all weak encryption types + * + * @param context Kerberos 5 context + * @param enable true to enable, false to disable + * + * @return Return an error code or 0. + * + * @ingroup krb5_crypto + */ + +KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL +krb5_allow_weak_crypto(krb5_context context, + krb5_boolean enable) +{ + int i; + + for(i = 0; i < num_etypes; i++) + if(etypes[i]->flags & F_WEAK) { + if(enable) + etypes[i]->flags &= ~F_DISABLED; + else + etypes[i]->flags |= F_DISABLED; + } + return 0; +} + KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL krb5_string_to_key_derived(krb5_context context, diff --git a/source4/heimdal/lib/krb5/get_cred.c b/source4/heimdal/lib/krb5/get_cred.c index 3d76391fa8f..75e44f0cd41 100644 --- a/source4/heimdal/lib/krb5/get_cred.c +++ b/source4/heimdal/lib/krb5/get_cred.c @@ -952,9 +952,7 @@ get_cred_kdc_referral(krb5_context context, ticket.server)) break; - if (ticket.server->name.name_string.len != 2 && - strcmp(ticket.server->name.name_string.val[0], KRB5_TGS_NAME) != 0) - { + if (!krb5_principal_is_krbtgt(context, ticket.server)) { krb5_set_error_message(context, KRB5KRB_AP_ERR_NOT_US, N_("Got back an non krbtgt " "ticket referrals", "")); diff --git a/source4/heimdal/lib/krb5/init_creds_pw.c b/source4/heimdal/lib/krb5/init_creds_pw.c index 4637a6d941c..f4437880757 100644 --- a/source4/heimdal/lib/krb5/init_creds_pw.c +++ b/source4/heimdal/lib/krb5/init_creds_pw.c @@ -134,12 +134,12 @@ free_init_creds_ctx(krb5_context context, krb5_init_creds_context ctx) free (ctx->pre_auth_types); if (ctx->in_tkt_service) free(ctx->in_tkt_service); - if (ctx->password) { - memset(ctx->password, 0, strlen(ctx->password)); - free(ctx->password); - } if (ctx->keytab_data) free(ctx->keytab_data); + if (ctx->password) { + memset(ctx->password, 0, strlen(ctx->password)); + free(ctx->password); + } krb5_data_free(&ctx->req_buffer); krb5_free_cred_contents(context, &ctx->cred); free_METHOD_DATA(&ctx->md); @@ -1436,8 +1436,8 @@ krb5_init_creds_set_password(krb5_context context, const char *password) { if (ctx->password) { - memset(ctx->password, 0, strlen(ctx->password)); - free(ctx->password); + memset(ctx->password, 0, strlen(ctx->password)); + free(ctx->password); } if (password) { ctx->password = strdup(password); diff --git a/source4/heimdal/lib/krb5/principal.c b/source4/heimdal/lib/krb5/principal.c index 00c967a72e8..8e6341fd62e 100644 --- a/source4/heimdal/lib/krb5/principal.c +++ b/source4/heimdal/lib/krb5/principal.c @@ -1551,3 +1551,17 @@ krb5_parse_nametype(krb5_context context, const char *str, int32_t *nametype) N_("Failed to find name type %s", ""), str); return KRB5_PARSE_MALFORMED; } + +/** + * Check if the cname part of the principal is a krbtgt principal + * + * @ingroup krb5_principal + */ + +krb5_boolean +krb5_principal_is_krbtgt(krb5_context context, krb5_const_principal p) +{ + return p->name.name_string.len == 2 && + strcmp(p->name.name_string.val[0], KRB5_TGS_NAME) == 0; + +} diff --git a/source4/heimdal/lib/krb5/rd_req.c b/source4/heimdal/lib/krb5/rd_req.c index 6b2ffbdaac4..9f6a85b1a22 100644 --- a/source4/heimdal/lib/krb5/rd_req.c +++ b/source4/heimdal/lib/krb5/rd_req.c @@ -821,7 +821,7 @@ out: * @param inbuf the (AP-REQ) authentication buffer * * @param server the server with authenticate as, if NULL the function - * will try to find any available credential in the keytab + * will try to find any avaiable credentintial in the keytab * that will verify the reply. The function will prefer the * server the server client specified in the AP-REQ, but if * there is no mach, it will try all keytab entries for a diff --git a/source4/heimdal/lib/krb5/send_to_kdc.c b/source4/heimdal/lib/krb5/send_to_kdc.c index a9be31e819f..9ff52fa545f 100644 --- a/source4/heimdal/lib/krb5/send_to_kdc.c +++ b/source4/heimdal/lib/krb5/send_to_kdc.c @@ -288,7 +288,7 @@ send_via_proxy (krb5_context context, return krb5_eai_to_heim_errno(ret, errno); for (a = ai; a != NULL; a = a->ai_next) { - s = socket (a->ai_family, a->ai_socktype, a->ai_protocol | SOCK_CLOEXEC); + s = socket (a->ai_family, a->ai_socktype | SOCK_CLOEXEC, a->ai_protocol); if (s < 0) continue; rk_cloexec(s); diff --git a/source4/heimdal/lib/krb5/ticket.c b/source4/heimdal/lib/krb5/ticket.c index 4d8da935790..e7d4d9532d5 100644 --- a/source4/heimdal/lib/krb5/ticket.c +++ b/source4/heimdal/lib/krb5/ticket.c @@ -443,9 +443,7 @@ check_server_referral(krb5_context context, return KRB5KRB_AP_ERR_MODIFIED; } - if (returned->name.name_string.len == 2 && - strcmp(returned->name.name_string.val[0], KRB5_TGS_NAME) == 0) - { + if (krb5_principal_is_krbtgt(context, returned)) { const char *realm = returned->name.name_string.val[1]; if (ref.referred_realm == NULL @@ -485,7 +483,13 @@ check_server_referral(krb5_context context, return ret; noreferral: - if (krb5_principal_compare(context, requested, returned) == FALSE) { + /* + * Expect excact match or that we got a krbtgt + */ + if (krb5_principal_compare(context, requested, returned) != TRUE && + (krb5_realm_compare(context, requested, returned) != TRUE && + krb5_principal_is_krbtgt(context, returned) != TRUE)) + { krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED, N_("Not same server principal returned " "as requested", "")); diff --git a/source4/heimdal/lib/roken/resolve.c b/source4/heimdal/lib/roken/resolve.c index 0c0fc1dd92b..e112274a682 100644 --- a/source4/heimdal/lib/roken/resolve.c +++ b/source4/heimdal/lib/roken/resolve.c @@ -521,8 +521,7 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) { struct rk_dns_reply *r; void *reply = NULL; - int size; - int len; + int size, len; #if defined(HAVE_DNS_SEARCH) struct sockaddr_storage from; uint32_t fromsize = sizeof(from); @@ -540,15 +539,12 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) return NULL; /* is this the best we can do? */ #endif - size = 0; - len = 1000; - do { + len = 1500; + while(1) { if (reply) { free(reply); reply = NULL; } - if (size <= len) - size = len; if (_resolve_debug) { #if defined(HAVE_DNS_SEARCH) dns_set_debug(handle, 1); @@ -556,27 +552,37 @@ dns_lookup_int(const char *domain, int rr_class, int rr_type) state.options |= RES_DEBUG; #endif fprintf(stderr, "dns_lookup(%s, %d, %s), buffer size %d\n", domain, - rr_class, rk_dns_type_to_string(rr_type), size); + rr_class, rk_dns_type_to_string(rr_type), len); } - reply = malloc(size); + reply = malloc(len); if (reply == NULL) { resolve_free_handle(handle); return NULL; } - len = resolve_search(handle, domain, rr_class, rr_type, reply, size); + size = resolve_search(handle, domain, rr_class, rr_type, reply, len); if (_resolve_debug) { fprintf(stderr, "dns_lookup(%s, %d, %s) --> %d\n", - domain, rr_class, rk_dns_type_to_string(rr_type), len); - } - if (len <= 0) { + domain, rr_class, rk_dns_type_to_string(rr_type), size); + } + if (size > len) { + /* resolver thinks it know better, go for it */ + len = size; + } else if (size > 0) { + /* got a good reply */ + break; + } else if (size <= 0 && len < rk_DNS_MAX_PACKET_SIZE) { + len *= 2; + if (len > rk_DNS_MAX_PACKET_SIZE) + len = rk_DNS_MAX_PACKET_SIZE; + } else { + /* the end, leave */ resolve_free_handle(handle); free(reply); return NULL; } - } while (size < len && len < rk_DNS_MAX_PACKET_SIZE); - resolve_free_handle(handle); + } len = min(len, size); r = parse_reply(reply, len); diff --git a/source4/heimdal/lib/roken/roken.h.in b/source4/heimdal/lib/roken/roken.h.in index 0492db4d6ba..76b083c7973 100644 --- a/source4/heimdal/lib/roken/roken.h.in +++ b/source4/heimdal/lib/roken/roken.h.in @@ -471,7 +471,7 @@ ROKEN_LIB_FUNCTION int ROKEN_LIB_CALL getdtablesize(void); ROKEN_LIB_FUNCTION char * ROKEN_LIB_CALL strerror(int); #endif -#if !defined(HAVE_STRERROR_R) && !defined(strerror_r) && !defined(STRERROR_R_PROTO_COMPATIBLE) +#if (!defined(HAVE_STRERROR_R) && !defined(strerror_r)) || (!defined(STRERROR_R_PROTO_COMPATIBLE) && defined(HAVE_STRERROR_R)) int ROKEN_LIB_FUNCTION rk_strerror_r(int, char *, size_t); #else #define rk_strerror_r strerror_r @@ -652,8 +652,14 @@ ROKEN_LIB_FUNCTION unsigned short ROKEN_LIB_CALL bswap16(unsigned short); int rk_flock(int fd, int operation); #endif /* HAVE_FLOCK */ -#if defined(SunOS) || defined(_AIX) +#ifndef HAVE_DIRFD +#ifdef HAVE_DIR_DD_FD #define dirfd(x) ((x)->dd_fd) +#else +#ifndef _WIN32 /* Windows code never calls dirfd */ +#error Missing dirfd() and ->dd_fd +#endif +#endif #endif ROKEN_LIB_FUNCTION time_t ROKEN_LIB_CALL tm2time (struct tm, int); @@ -1033,6 +1039,12 @@ void rk_qsort(void *, size_t, size_t, int (*)(const void *, const void *)); #endif +#if defined(__linux__) && SOCK_CLOEXEC && !defined(SOCKET_WRAPPER_REPLACE) +#undef socket +#define socket(_fam,_type,_prot) rk_socket(_fam,_type,_prot) +int ROKEN_LIB_FUNCTION rk_socket(int, int, int); +#endif + #ifdef SOCKET_WRAPPER_REPLACE #include #endif diff --git a/source4/heimdal/lib/roken/socket.c b/source4/heimdal/lib/roken/socket.c index bfc4b7102b8..bd800ac5a1c 100644 --- a/source4/heimdal/lib/roken/socket.c +++ b/source4/heimdal/lib/roken/socket.c @@ -315,3 +315,24 @@ socket_to_fd(rk_socket_t sock, int flags) return _open_osfhandle((intptr_t) sock, flags); #endif } + +#ifndef HEIMDAL_SMALLER +#undef socket + +int rk_socket(int, int, int); + +int +rk_socket(int domain, int type, int protocol) +{ + int s; + s = socket (domain, type, protocol); +#ifdef SOCK_CLOEXEC + if ((SOCK_CLOEXEC & type) && s < 0 && errno == EINVAL) { + type &= ~SOCK_CLOEXEC; + s = socket (domain, type, protocol); + } +#endif + return s; +} + +#endif /* HEIMDAL_SMALLER */ diff --git a/source4/heimdal/lib/roken/strerror_r.c b/source4/heimdal/lib/roken/strerror_r.c index 63dae09a7da..5155c28cb56 100644 --- a/source4/heimdal/lib/roken/strerror_r.c +++ b/source4/heimdal/lib/roken/strerror_r.c @@ -33,11 +33,12 @@ #include -#if !defined(HAVE_STRERROR_R) && !defined(STRERROR_R_PROTO_COMPATIBLE) +#if (!defined(HAVE_STRERROR_R) && !defined(strerror_r)) || (!defined(STRERROR_R_PROTO_COMPATIBLE) && defined(HAVE_STRERROR_R)) #include #include #include +#include "roken.h" #ifdef _MSC_VER @@ -58,11 +59,6 @@ rk_strerror_r(int eno, char * strerrbuf, size_t buflen) #else /* _MSC_VER */ -#ifndef HAVE_STRERROR_R -extern int sys_nerr; -extern char *sys_errlist[]; -#endif - int ROKEN_LIB_FUNCTION rk_strerror_r(int eno, char *strerrbuf, size_t buflen) { @@ -76,11 +72,7 @@ rk_strerror_r(int eno, char *strerrbuf, size_t buflen) return 0; #else int ret; - if(eno < 0 || eno >= sys_nerr) { - snprintf(strerrbuf, buflen, "Error %d occurred.", eno); - return EINVAL; - } - ret = snprintf(strerrbuf, buflen, "%s", sys_errlist[eno]); + ret = strlcpy(strerrbuf, buflen, strerror(eno)); if (ret > buflen) return ERANGE; return 0; -- 2.11.4.GIT