]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
third_party/heimdal: Import lorikeet-heimdal-202503211313 (commit f5c091eff46b975ede0...
authorStefan Metzmacher <metze@samba.org>
Fri, 21 Mar 2025 12:23:41 +0000 (13:23 +0100)
committerRalph Boehme <slow@samba.org>
Thu, 3 Apr 2025 09:36:31 +0000 (09:36 +0000)
This is a rebase on Heimdal master as well as
some patches to prepare sid-filtering support in Samba.

NOTE: THIS COMMIT WON’T COMPILE/WORK ON ITS OWN!

Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
33 files changed:
third_party/heimdal/.gitignore
third_party/heimdal/appl/test/auditdns.c
third_party/heimdal/cf/find-func-no-libs2.m4
third_party/heimdal/cf/have-struct-field.m4
third_party/heimdal/kdc/fast.c
third_party/heimdal/kdc/kdc-accessors.h
third_party/heimdal/kdc/kdc-plugin.c
third_party/heimdal/kdc/kdc.h
third_party/heimdal/kdc/kdc_locl.h
third_party/heimdal/kdc/kerberos5.c
third_party/heimdal/kdc/krb5tgs.c
third_party/heimdal/kdc/libkdc-exports.def
third_party/heimdal/kdc/mssfu.c
third_party/heimdal/kdc/version-script.map
third_party/heimdal/lib/gssapi/krb5/arcfour.c
third_party/heimdal/lib/gssapi/krb5/cfx.c
third_party/heimdal/lib/gssapi/krb5/sequence.c
third_party/heimdal/lib/gssapi/krb5/unwrap.c
third_party/heimdal/lib/gssapi/krb5/verify_mic.c
third_party/heimdal/lib/hcrypto/libtommath/bn_mp_2expt.c
third_party/heimdal/lib/hcrypto/libtommath/bn_mp_grow.c
third_party/heimdal/lib/hcrypto/libtommath/bn_mp_init_size.c
third_party/heimdal/lib/hcrypto/libtommath/bn_mp_mul_2d.c
third_party/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs.c
third_party/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_digs_fast.c
third_party/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs.c
third_party/heimdal/lib/hcrypto/libtommath/bn_s_mp_mul_high_digs_fast.c
third_party/heimdal/lib/hdb/hdb.h
third_party/heimdal/lib/krb5/fast.c
third_party/heimdal/lib/krb5/fcache.c
third_party/heimdal/lib/krb5/krbhst.c
third_party/heimdal/lib/krb5/salt-des.c
third_party/heimdal/lib/otp/otp_db.c

index e5b52468af54915ee626c7314f487844b8e5bc99..6a56c208980105362e3b2451fe218862ca4e128c 100644 (file)
@@ -44,11 +44,14 @@ asn1_*_asn1.c
 /aclocal.m4
 /autom4te.cache
 /compile
+/confdefs.h
 /config.guess
 /config.log
 /config.status
 /config.sub
 /configure
+/conftest.c
+/conftest.err
 /depcomp
 /install-sh
 /libtool
@@ -58,6 +61,7 @@ asn1_*_asn1.c
 /stage1.diff
 /stage2.diff
 /test-driver
+/tmp.h
 /ylwrap
 
 /lib/libedit/aclocal.m4
index 4f5b1dde5d6edf964ef34bf15c61563756f516fa..3a79af45e61cf4dce933b06be7705cefda003ea3 100644 (file)
 #include "resolve.h"
 #include "roken.h"
 
+#if (__STDC_VERSION__ - 0) < 199901L
+# define restrict /* empty */
+#endif
+
 struct rk_dns_reply *
 rk_dns_lookup(const char *domain, const char *type_name)
 {
index 5e5ed0e69ba60f7beb1999e5bb1ef80e5b35de56..a6b3ad6d347adc943b208a7e185d3c426996929e 100644 (file)
@@ -21,7 +21,7 @@ if eval "test \"\$ac_cv_func_$1\" != yes" ; then
                *) ac_lib="-l$ac_lib" ;;
                esac
                LIBS="$6 $ac_lib $5 $ac_save_LIBS"
-               AC_LINK_IFELSE([AC_LANG_PROGRAM([[$3]],[[$1($4)]])],[eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break])
+               AC_LINK_IFELSE([AC_LANG_PROGRAM([[char $1 (void);]],[[$1()]])],[eval "if test -n \"$ac_lib\";then ac_cv_funclib_$1=$ac_lib; else ac_cv_funclib_$1=yes; fi";break])
        done
        eval "ac_cv_funclib_$1=\${ac_cv_funclib_$1-no}"
        LIBS="$ac_save_LIBS"
index bb7bcefbcc68a08cef3f7ae721ab226397adda50..3962d850645f88e4b18eaf3f084bdb733f5100d7 100644 (file)
@@ -7,7 +7,8 @@ dnl AC_HAVE_STRUCT_FIELD(struct, field, headers)
 AC_DEFUN([AC_HAVE_STRUCT_FIELD], [
 define(cache_val, translit(ac_cv_type_$1_$2, [A-Z ], [a-z_]))
 AC_CACHE_CHECK([for $2 in $1], cache_val,[
-AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[$3]],
+AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include <string.h>
+$3]],
        [[$1 x; memset(&x, 0, sizeof(x)); x.$2]])],
        [cache_val=yes],
        [cache_val=no])
index d6b6ab2bbb3618c6aa4e434719d7f0b7d156d871..235cdc5e3f083b303696577358ea337ec50f97f0 100644 (file)
@@ -953,6 +953,11 @@ _kdc_fast_check_armor_pac(astgs_request_t r, int flags)
     if (r->req.req_body.kdc_options.canonicalize)
        flags |= HDB_F_CANON;
 
+    if (krb5_principal_is_krbtgt(r->context, r->armor_server->principal) &&
+       !krb5_principal_is_root_krbtgt(r->context, r->armor_server->principal)) {
+       flags |= HDB_F_CROSS_REALM_PRINCIPAL;
+    }
+
     ret = _krb5_principalname2krb5_principal(r->context,
                                             &armor_client_principal,
                                             r->armor_ticket->ticket.cname,
@@ -996,6 +1001,9 @@ _kdc_fast_check_armor_pac(astgs_request_t r, int flags)
     r->armor_clientdb = armor_db;
     armor_db = NULL;
 
+    r->armor_client_principal = armor_client_principal;
+    armor_client_principal = NULL;
+
     r->armor_client = armor_client;
     armor_client = NULL;
 
index 8d1305a139ee5366777200414c703e8fa0acb567..76415f65e2024a32d3faabca56a06c9f410431c7 100644 (file)
@@ -359,6 +359,9 @@ kdc_request_get_explicit_armor_clientdb(astgs_request_t);
 KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
 kdc_request_get_explicit_armor_client(astgs_request_t);
 
+KDC_LIB_FUNCTION const Principal * KDC_LIB_CALL
+kdc_request_get_explicit_armor_client_principal(astgs_request_t);
+
 KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
 kdc_request_get_explicit_armor_server(astgs_request_t);
 
@@ -378,6 +381,13 @@ ASTGS_REQUEST_GET_ACCESSOR_PTR(HDB *, armor_clientdb)
  */
 ASTGS_REQUEST_GET_ACCESSOR_PTR(hdb_entry *, armor_client);
 
+/*
+ * const Principal *
+ * kdc_request_get_armor_client_principal(astgs_request_t);
+ */
+
+ASTGS_REQUEST_GET_ACCESSOR_PTR(Principal *, armor_client_principal)
+
 /*
  * const hdb_entry *
  * kdc_request_get_armor_server(astgs_request_t);
index bf41099d9b0fe8e55378d2b9c2216bed129a252e..e358626c6caf91daccef88d7353572ce5ecaf611 100644 (file)
@@ -767,6 +767,12 @@ kdc_request_get_explicit_armor_client(astgs_request_t r)
     return r->explicit_armor_present ? r->armor_client : NULL;
 }
 
+KDC_LIB_FUNCTION const Principal * KDC_LIB_CALL
+kdc_request_get_explicit_armor_client_principal(astgs_request_t r)
+{
+    return r->explicit_armor_present ? r->armor_client_principal : NULL;
+}
+
 KDC_LIB_FUNCTION const hdb_entry * KDC_LIB_CALL
 kdc_request_get_explicit_armor_server(astgs_request_t r)
 {
index 057d29a02a10c521da8420c5ebe517ac84dcc7ca..857e3251959e2e65084b2e8341397d0093050291 100644 (file)
@@ -49,7 +49,8 @@
 enum krb5_kdc_trpolicy {
     TRPOLICY_ALWAYS_CHECK,
     TRPOLICY_ALLOW_PER_PRINCIPAL,
-    TRPOLICY_ALWAYS_HONOUR_REQUEST
+    TRPOLICY_ALWAYS_HONOUR_REQUEST,
+    TRPOLICY_NEVER_CHECK,
 };
 
 struct krb5_kdc_configuration;
@@ -114,7 +115,8 @@ struct krb5_kdc_service {
     unsigned int require_pac : 1;                              \
     unsigned int enable_fast : 1;                              \
     unsigned int enable_fast_cookie : 1;                       \
-    unsigned int enable_armored_pa_enc_timestamp : 1
+    unsigned int enable_armored_pa_enc_timestamp : 1;          \
+    enum krb5_kdc_trpolicy trpolicy
 
 #ifndef __KDC_LOCL_H__
 struct krb5_kdc_configuration {
index d56d6b557b9644577ace04aee7d3663a247ebd95..7db8f0117ab025f52f721d6fcf5d29580db905d7 100644 (file)
@@ -84,7 +84,6 @@ struct krb5_kdc_configuration {
     unsigned int allow_anonymous : 1;
     unsigned int historical_anon_realm : 1;
     unsigned int strict_nametypes : 1;
-    enum krb5_kdc_trpolicy trpolicy;
 
     unsigned int disable_pac : 1;
     unsigned int enable_unarmored_pa_enc_timestamp : 1;
@@ -179,6 +178,7 @@ struct astgs_request_desc {
     krb5_ticket *armor_ticket;
     Key *armor_key;
 
+    krb5_principal armor_client_principal;
     hdb_entry *armor_client;
     HDB *armor_clientdb;
     krb5_pac armor_pac;
index 3bcf00c984b54e22c22b0790e3ce91fe2649faf8..4c0362c8fd560d49ce23b0135bc9c05506258651 100644 (file)
@@ -1384,8 +1384,8 @@ struct kdc_patypes {
 #define PA_SYNTHETIC_OK        4
 #define PA_REPLACE_REPLY_KEY   8   /* PA mech replaces reply key */
 #define PA_USES_LONG_TERM_KEY  16  /* PA mech uses client's long-term key */
-#define PA_USES_FAST_COOKIE    32  /* Multi-step PA mech maintains state in PA-FX-COOKIE */
-#define PA_HARDWARE_AUTH       64  /* PA mech uses hardware authentication */
+#define PA_HARDWARE_AUTH       32  /* PA mech uses hardware authentication */
+#define PA_USES_FAST_COOKIE    64  /* Multi-step PA mech maintains state in PA-FX-COOKIE */
     krb5_error_code (*validate)(astgs_request_t, const PA_DATA *pa);
     krb5_error_code (*finalize_pac)(astgs_request_t r);
     void (*cleanup)(astgs_request_t r);
@@ -1584,7 +1584,7 @@ _kdc_encode_reply(krb5_context context,
         * Hide client name for privacy reasons
         */
        if (r->fast.flags.requested_hidden_names) {
-           Realm anon_realm = KRB5_ANON_REALM;
+           const Realm anon_realm = KRB5_ANON_REALM;
 
            free_Realm(&rep->crealm);
            ret = copy_Realm(&anon_realm, &rep->crealm);
@@ -2849,7 +2849,7 @@ _kdc_as_rep(astgs_request_t r)
 
     if (!config->historical_anon_realm &&
         _kdc_is_anonymous(r->context, r->client_princ)) {
-       Realm anon_realm = KRB5_ANON_REALM;
+       const Realm anon_realm = KRB5_ANON_REALM;
        ret = copy_Realm(&anon_realm, &rep->crealm);
     } else if (f.canonicalize || r->client->flags.force_canonicalize)
        ret = copy_Realm(&r->canon_client_princ->realm, &rep->crealm);
@@ -3248,6 +3248,16 @@ out:
        krb5_free_ticket(r->context, r->armor_ticket);
     if (r->armor_server)
        _kdc_free_ent(r->context, r->armor_serverdb, r->armor_server);
+    if (r->armor_client_principal) {
+       krb5_free_principal(r->context, r->armor_client_principal);
+       r->armor_client_principal = NULL;
+    }
+    if (r->armor_client)
+       _kdc_free_ent(r->context,
+                     r->armor_clientdb,
+                     r->armor_client);
+    if (r->armor_pac)
+       krb5_pac_free(r->context, r->armor_pac);
     krb5_free_keyblock_contents(r->context, &r->reply_key);
     krb5_free_keyblock_contents(r->context, &r->enc_ad_key);
     krb5_free_keyblock_contents(r->context, &r->session_key);
index d744f5610f359d86458c676cf1d42cfa4827b3fb..f8fe63d88d7fb637409cc313be22e8d0f067ab78 100644 (file)
@@ -550,6 +550,7 @@ tgs_make_reply(astgs_request_t r,
     KDCOptions f = b->kdc_options;
     krb5_error_code ret;
     int is_weak = 0;
+    krb5_boolean check_policy = FALSE;
 
     heim_assert(r->client_princ != NULL, "invalid client name passed to tgs_make_reply");
 
@@ -581,18 +582,30 @@ tgs_make_reply(astgs_request_t r,
     (r->config->trpolicy == TRPOLICY_ALLOW_PER_PRINCIPAL)
 #define GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK                   \
     (r->config->trpolicy == TRPOLICY_ALWAYS_HONOUR_REQUEST)
+#define GLOBAL_DISABLE_TRANSITED_CHECK         \
+    (r->config->trpolicy == TRPOLICY_NEVER_CHECK)
 
 /* these will consult the database in future release */
 #define PRINCIPAL_FORCE_TRANSITED_CHECK(P)             0
 #define PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(P)     0
 
+    if (GLOBAL_DISABLE_TRANSITED_CHECK) {
+       check_policy = FALSE;
+    } else if (!f.disable_transited_check) {
+       check_policy = TRUE;
+    } else if (GLOBAL_FORCE_TRANSITED_CHECK) {
+       check_policy = TRUE;
+    } else if (PRINCIPAL_FORCE_TRANSITED_CHECK(r->server)) {
+       check_policy = TRUE;
+    } else if (!((GLOBAL_ALLOW_PER_PRINCIPAL &&
+              PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(r->server)) ||
+              GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK))
+    {
+       check_policy = TRUE;
+    }
+
     ret = fix_transited_encoding(r->context, r->config,
-                                !f.disable_transited_check ||
-                                GLOBAL_FORCE_TRANSITED_CHECK ||
-                                PRINCIPAL_FORCE_TRANSITED_CHECK(r->server) ||
-                                !((GLOBAL_ALLOW_PER_PRINCIPAL &&
-                                   PRINCIPAL_ALLOW_DISABLE_TRANSITED_CHECK(r->server)) ||
-                                  GLOBAL_ALLOW_DISABLE_TRANSITED_CHECK),
+                                check_policy,
                                 &tgt->transited, et,
                                 krb5_principal_get_realm(r->context, r->client_princ),
                                 krb5_principal_get_realm(r->context, r->server->principal),
@@ -688,6 +701,10 @@ tgs_make_reply(astgs_request_t r,
     et->flags.hw_authent  = tgt->flags.hw_authent;
     et->flags.ok_as_delegate = r->server->flags.ok_as_delegate;
 
+    /* See MS-KILE 3.3.5.7.5 Cross-Domain Trust and Referrals */
+    if (!r->krbtgt->flags.ok_as_delegate)
+       et->flags.ok_as_delegate = 0;
+
     /* See MS-KILE 3.3.5.1 */
     if (!r->server->flags.forwardable)
        et->flags.forwardable = 0;
@@ -1307,6 +1324,9 @@ _kdc_db_fetch_client(krb5_context context,
         * This is OK, we are just trying to find out if they have
         * been disabled or deleted in the meantime; missing secrets
         * are OK.
+        *
+        * If HDB_F_CROSS_REALM_PRINCIPAL was passed this
+        * indicates the client is remote.
         */
     } else if (ret) {
        /*
@@ -1717,7 +1737,7 @@ server_lookup:
             * proper checks.
             */
            ret = _kdc_db_fetch(context, config, user2user_princ,
-                               HDB_F_GET_CLIENT | flags,
+                               HDB_F_GET_CLIENT | HDB_F_USER2USER_PRINCIPAL | flags,
                                NULL, &user2user_db, &user2user_client);
            if (ret == HDB_ERR_NOENTRY)
                ret = KRB5KDC_ERR_C_PRINCIPAL_UNKNOWN;
@@ -1877,6 +1897,9 @@ server_lookup:
     if (_kdc_synthetic_princ_used_p(context, priv->ticket))
        flags |= HDB_F_SYNTHETIC_OK;
 
+    if (!krb5_principal_compare(context, priv->krbtgt->principal, krbtgt_out->principal))
+       flags |= HDB_F_CROSS_REALM_PRINCIPAL;
+
     ret = _kdc_db_fetch_client(context, config, flags, priv->client_princ,
                               cpn, our_realm, &clientdb, &priv->client);
     if (ret)
@@ -2293,6 +2316,10 @@ out:
        krb5_free_ticket(r->context, r->armor_ticket);
     if (r->armor_server)
        _kdc_free_ent(r->context, r->armor_serverdb, r->armor_server);
+    if (r->armor_client_principal) {
+       krb5_free_principal(r->context, r->armor_client_principal);
+       r->armor_client_principal = NULL;
+    }
     if (r->armor_client)
        _kdc_free_ent(r->context,
                      r->armor_clientdb,
index 1c6997a23c26204a65fbfa07d8a60a953a6f1077..0499b1f0c9dbd0523f08e81012e60b592fdedf40 100644 (file)
@@ -28,6 +28,7 @@ EXPORTS
        kdc_request_get_addr
        kdc_request_get_armor_client
        kdc_request_get_armor_clientdb
+       kdc_request_get_armor_client_principal
        kdc_request_get_armor_pac
        kdc_request_get_armor_server
        kdc_request_get_canon_client_princ
@@ -41,6 +42,7 @@ EXPORTS
        kdc_request_get_explicit_armor_pac
        kdc_request_get_explicit_armor_clientdb
        kdc_request_get_explicit_armor_client
+       kdc_request_get_explicit_armor_client_principal
        kdc_request_get_explicit_armor_present
        kdc_request_get_explicit_armor_server
        kdc_request_get_from
index 554e2f2112ab66ba282b937c655b410269c19048..92ec65e15ae08b6cdd07d670706bf5882621696f 100644 (file)
@@ -107,8 +107,10 @@ check_rbcd(krb5_context context,
           HDB *clientdb,
           krb5_const_principal s4u_principal,
           const hdb_entry *client_krbtgt,
+          krb5_const_principal client_principal,
           const hdb_entry *client,
           const hdb_entry *device_krbtgt,
+          krb5_const_principal device_principal,
           const hdb_entry *device,
           krb5_const_pac client_pac,
           krb5_const_pac device_pac,
@@ -120,8 +122,10 @@ check_rbcd(krb5_context context,
        ret = clientdb->hdb_check_rbcd(context,
                                       clientdb,
                                       client_krbtgt,
+                                      client_principal,
                                       client,
                                       device_krbtgt,
+                                      device_principal,
                                       device,
                                       s4u_principal,
                                       client_pac,
@@ -150,7 +154,7 @@ _kdc_validate_protocol_transition(astgs_request_t r, const PA_DATA *for_user)
     EncTicketPart *ticket = &r->ticket->ticket;
     hdb_entry *s4u_client = NULL;
     HDB *s4u_clientdb;
-    int flags = HDB_F_FOR_TGS_REQ;
+    int flags = HDB_F_FOR_TGS_REQ | HDB_F_S4U2SELF_PRINCIPAL;
     krb5_principal s4u_client_name = NULL, s4u_canon_client_name = NULL;
     krb5_pac s4u_pac = NULL;
     char *s4ucname = NULL;
@@ -375,7 +379,7 @@ _kdc_validate_constrained_delegation(astgs_request_t r)
 {
     krb5_error_code ret;
     KDC_REQ_BODY *b = &r->req.req_body;
-    int flags = HDB_F_FOR_TGS_REQ;
+    int flags = HDB_F_FOR_TGS_REQ | HDB_F_S4U2PROXY_PRINCIPAL;
     krb5_principal s4u_client_name = NULL, s4u_server_name = NULL;
     krb5_principal s4u_canon_client_name = NULL;
     krb5_pac s4u_pac = NULL;
@@ -542,9 +546,14 @@ _kdc_validate_constrained_delegation(astgs_request_t r)
     if (rbcd_support) {
        ret = check_rbcd(r->context, r->config, r->clientdb,
                         s4u_client_name,
-                        r->krbtgt, r->client,
-                        r->armor_server, r->armor_client,
-                        r->pac, r->armor_pac,
+                        r->krbtgt,
+                        r->client_princ,
+                        r->client,
+                        r->armor_server,
+                        r->armor_client_principal,
+                        r->armor_client,
+                        r->pac,
+                        r->armor_pac,
                         r->server);
     } else {
        ret = KRB5KDC_ERR_BADOPTION;
@@ -577,6 +586,10 @@ _kdc_validate_constrained_delegation(astgs_request_t r)
        goto out;
     }
 
+    /* s4u_client_name can be remote */
+    if (!krb5_realm_compare(r->context, s4u_client_name, s4u_server_name))
+       flags |= HDB_F_CROSS_REALM_PRINCIPAL;
+
     /* Try lookup the delegated client in DB */
     ret = _kdc_db_fetch_client(r->context, r->config, flags,
                               s4u_client_name, s4ucname, local_realm,
index 508357d0a7d030080cd997fd12e4e2725cacfb45..808f9f7431455df7552e897f58043c6e9f04b13d 100644 (file)
@@ -31,6 +31,7 @@ HEIMDAL_KDC_1.0 {
                kdc_request_get_addr;
                kdc_request_get_armor_client;
                kdc_request_get_armor_clientdb;
+               kdc_request_get_armor_client_principal;
                kdc_request_get_armor_pac;
                kdc_request_get_armor_server;
                kdc_request_get_canon_client_princ;
@@ -44,6 +45,7 @@ HEIMDAL_KDC_1.0 {
                kdc_request_get_explicit_armor_pac;
                kdc_request_get_explicit_armor_clientdb;
                kdc_request_get_explicit_armor_client;
+               kdc_request_get_explicit_armor_client_principal;
                kdc_request_get_explicit_armor_present;
                kdc_request_get_explicit_armor_server;
                kdc_request_get_from;
index 787a8d3d2d601bf0643f3bd02af5b9b3467d2db6..02780b62189e462b3185cf6a03c030caf4ef4052 100644 (file)
@@ -740,15 +740,15 @@ OM_uint32 _gssapi_unwrap_arcfour(OM_uint32 *minor_status,
        return GSS_S_BAD_MIC;
     }
 
+    if (conf_state)
+       *conf_state = conf_flag;
+
     HEIMDAL_MUTEX_lock(&context_handle->ctx_id_mutex);
     omret = _gssapi_msg_order_check(context_handle->order, seq_number);
     HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
     if (omret)
        return omret;
 
-    if (conf_state)
-       *conf_state = conf_flag;
-
     *minor_status = 0;
     return GSS_S_COMPLETE;
 }
@@ -1375,6 +1375,10 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
        }
     }
 
+    if (pconf_state) {
+       *pconf_state = conf_state;
+    }
+
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
     ret = _gssapi_msg_order_check(ctx->order, seq_number);
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
@@ -1382,10 +1386,6 @@ _gssapi_unwrap_iov_arcfour(OM_uint32 *minor_status,
        return ret;
     }
 
-    if (pconf_state) {
-       *pconf_state = conf_state;
-    }
-
     *minor_status = 0;
     return GSS_S_COMPLETE;
 }
index cb9ea773bbb50a2445c5c9c50ae424889b1e2021..af50292c28672e0cfbf3ba11cee3a58353182349 100644 (file)
@@ -748,7 +748,7 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
     gss_iov_buffer_desc *header, *trailer, *padding;
     gss_cfx_wrap_token token, ttoken;
     u_char token_flags;
-    krb5_error_code ret;
+    krb5_error_code ret, seq_err;
     unsigned usage;
     uint16_t ec, rrc;
     krb5_crypto_iov *data = NULL;
@@ -818,17 +818,16 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
     if (seq_number_hi) {
        /* no support for 64-bit sequence numbers */
        *minor_status = ERANGE;
-       return GSS_S_UNSEQ_TOKEN;
+       return GSS_S_FAILURE | GSS_S_UNSEQ_TOKEN;
     }
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
-    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
-    if (ret != 0) {
-       *minor_status = 0;
-       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
-       return ret;
-    }
+    seq_err = _gssapi_msg_order_check(ctx->order, seq_number_lo);
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+    if (seq_err == GSS_S_FAILURE) {
+       *minor_status = 0;
+       return seq_err;
+    }
 
     /*
      * Decrypt and/or verify checksum
@@ -1025,7 +1024,7 @@ _gssapi_unwrap_cfx_iov(OM_uint32 *minor_status,
     free(data);
 
     *minor_status = 0;
-    return GSS_S_COMPLETE;
+    return GSS_S_COMPLETE | seq_err;
 
  failure:
     if (data)
@@ -1401,7 +1400,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
 {
     gss_cfx_wrap_token token;
     u_char token_flags;
-    krb5_error_code ret;
+    krb5_error_code ret, seq_err;
     unsigned usage;
     krb5_data data;
     uint16_t ec, rrc;
@@ -1459,18 +1458,16 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
     if (seq_number_hi) {
        /* no support for 64-bit sequence numbers */
        *minor_status = ERANGE;
-       return GSS_S_UNSEQ_TOKEN;
+       return GSS_S_FAILURE | GSS_S_UNSEQ_TOKEN;
     }
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
-    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
-    if (ret != 0) {
-       *minor_status = 0;
-       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
-       _gsskrb5_release_buffer(minor_status, output_message_buffer);
-       return ret;
-    }
+    seq_err = _gssapi_msg_order_check(ctx->order, seq_number_lo);
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+    if (seq_err == GSS_S_FAILURE) {
+       *minor_status = 0;
+       return seq_err;
+    }
 
     /*
      * Decrypt and/or verify checksum
@@ -1594,7 +1591,7 @@ OM_uint32 _gssapi_unwrap_cfx(OM_uint32 *minor_status,
     }
 
     *minor_status = 0;
-    return GSS_S_COMPLETE;
+    return GSS_S_COMPLETE | seq_err;
 }
 
 OM_uint32 _gssapi_mic_cfx(OM_uint32 *minor_status,
@@ -1690,7 +1687,7 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
 {
     gss_cfx_mic_token token;
     u_char token_flags;
-    krb5_error_code ret;
+    krb5_error_code ret, seq_err;
     unsigned usage;
     OM_uint32 seq_number_lo, seq_number_hi;
     u_char *buf, *p;
@@ -1736,17 +1733,16 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
     _gss_mg_decode_be_uint32(&token->SND_SEQ[4], &seq_number_lo);
     if (seq_number_hi) {
        *minor_status = ERANGE;
-       return GSS_S_UNSEQ_TOKEN;
+       return GSS_S_UNSEQ_TOKEN | GSS_S_FAILURE;
     }
 
     HEIMDAL_MUTEX_lock(&ctx->ctx_id_mutex);
-    ret = _gssapi_msg_order_check(ctx->order, seq_number_lo);
-    if (ret != 0) {
-       *minor_status = 0;
-       HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
-       return ret;
-    }
+    seq_err = _gssapi_msg_order_check(ctx->order, seq_number_lo);
     HEIMDAL_MUTEX_unlock(&ctx->ctx_id_mutex);
+    if (seq_err == GSS_S_FAILURE) {
+       *minor_status = 0;
+       return seq_err;
+    }
 
     /*
      * Verify checksum
@@ -1793,5 +1789,5 @@ OM_uint32 _gssapi_verify_mic_cfx(OM_uint32 *minor_status,
        *qop_state = GSS_C_QOP_DEFAULT;
     }
 
-    return GSS_S_COMPLETE;
+    return GSS_S_COMPLETE | seq_err;
 }
index 2e0e7b20f922565ca6f4a4bf2b1efff2a74d56a1..56ce447f537f045672e50bf652d49c8568cca2d3 100644 (file)
@@ -188,7 +188,7 @@ _gssapi_msg_order_check(struct gss_msg_order *o, OM_uint32 seq_num)
     for (i = 0; i < o->length - 1; i++) {
        if (o->elem[i] == seq_num)
            return GSS_S_DUPLICATE_TOKEN;
-       if (o->elem[i + 1] < seq_num && o->elem[i] < seq_num) {
+       if (o->elem[i + 1] < seq_num && o->elem[i] > seq_num) {
            elem_insert(o, i, seq_num);
            if (r)
                return GSS_S_COMPLETE;
index 1eea68eace289fcf8fa6a0bb36e54b55ec8fbcfe..9e45fbd27453cfd934e64f3cf893174249d79134 100644 (file)
@@ -57,7 +57,7 @@ unwrap_des
   size_t i;
   uint32_t seq_number;
   size_t padlength;
-  OM_uint32 ret;
+  OM_uint32 ret, seq_err;
   int cstate;
   int cmp;
   int token_len;
@@ -175,10 +175,10 @@ unwrap_des
     return GSS_S_BAD_MIC;
   }
 
-  ret = _gssapi_msg_order_check(context_handle->order, seq_number);
-  if (ret) {
+  seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
+  if (seq_err == GSS_S_FAILURE) {
     HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
-    return ret;
+    return seq_err;
   }
 
   HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -194,7 +194,7 @@ unwrap_des
       memcpy (output_message_buffer->value,
              p + 24,
              output_message_buffer->length);
-  return GSS_S_COMPLETE;
+  return GSS_S_COMPLETE | seq_err;
 }
 #endif
 
@@ -217,7 +217,7 @@ unwrap_des3
   u_char cksum[20];
   uint32_t seq_number;
   size_t padlength;
-  OM_uint32 ret;
+  OM_uint32 ret, seq_err;
   int cstate;
   krb5_crypto crypto;
   Checksum csum;
@@ -349,11 +349,11 @@ unwrap_des3
       return GSS_S_BAD_MIC;
   }
 
-  ret = _gssapi_msg_order_check(context_handle->order, seq_number);
-  if (ret) {
+  seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
+  if (seq_err == GSS_S_FAILURE) {
       *minor_status = 0;
       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
-      return ret;
+      return seq_err;
   }
 
   HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -396,7 +396,7 @@ unwrap_des3
       memcpy (output_message_buffer->value,
              p + 36,
              output_message_buffer->length);
-  return GSS_S_COMPLETE;
+  return GSS_S_COMPLETE | seq_err;
 }
 
 OM_uint32 GSSAPI_CALLCONV _gsskrb5_unwrap
index 4a776c8099b6ad2aa7f42d3f83c4c6970de42222..3b97a90599418f428b931984fed4973492facd09 100644 (file)
@@ -148,7 +148,7 @@ verify_mic_des3
   u_char *p;
   u_char *seq;
   uint32_t seq_number;
-  OM_uint32 ret;
+  OM_uint32 ret, seq_err;
   krb5_crypto crypto;
   krb5_data seq_data;
   int cmp, docompat;
@@ -226,8 +226,8 @@ retry:
       return GSS_S_BAD_MIC;
   }
 
-  ret = _gssapi_msg_order_check(context_handle->order, seq_number);
-  if (ret) {
+  seq_err = _gssapi_msg_order_check(context_handle->order, seq_number);
+  if (seq_err == GSS_S_FAILURE) {
       krb5_crypto_destroy (context, crypto);
       *minor_status = 0;
       HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
@@ -269,7 +269,7 @@ retry:
   HEIMDAL_MUTEX_unlock(&context_handle->ctx_id_mutex);
 
   krb5_crypto_destroy (context, crypto);
-  return GSS_S_COMPLETE;
+  return GSS_S_COMPLETE | seq_err;
 }
 
 OM_uint32
index 0ae3df1bf95343fe01f3fac1d62aac6421094bca..23de0c3c5d1e4871e59afc06f1306f98707d2330 100644 (file)
@@ -12,6 +12,10 @@ mp_err mp_2expt(mp_int *a, int b)
 {
    mp_err    err;
 
+   if (b < 0) {
+      return MP_VAL;
+   }
+
    /* zero a as per default */
    mp_zero(a);
 
index 9e904c547e11b723c7c692220bbafb9d8fd65e6e..2b1682651894af48547220107247e9e9c6e67acd 100644 (file)
@@ -9,6 +9,10 @@ mp_err mp_grow(mp_int *a, int size)
    int     i;
    mp_digit *tmp;
 
+   if (size < 0) {
+      return MP_VAL;
+   }
+
    /* if the alloc size is smaller alloc more ram */
    if (a->alloc < size) {
       /* reallocate the array a->dp
index d62268721a828693373b6f2146fa625dd6398d71..99573833fbc92aa91b1d1b3fe6cea67176a41e38 100644 (file)
@@ -6,6 +6,11 @@
 /* init an mp_init for a given size */
 mp_err mp_init_size(mp_int *a, int size)
 {
+
+   if (size < 0) {
+      return MP_VAL;
+   }
+
    size = MP_MAX(MP_MIN_PREC, size);
 
    /* alloc mem */
index 87354de20245b0f5bb89f09a640dcd650f5f8212..bfeaf2eb226fa79bf1fad4aa139a498d05ed46c4 100644 (file)
@@ -9,6 +9,10 @@ mp_err mp_mul_2d(const mp_int *a, int b, mp_int *c)
    mp_digit d;
    mp_err   err;
 
+   if (b < 0) {
+      return MP_VAL;
+   }
+
    /* copy */
    if (a != c) {
       if ((err = mp_copy(a, c)) != MP_OKAY) {
index 64509d4cb931701afb738a98d03e75bce5d253a7..3682b49800aa89e29b943afd0b707eb413675872 100644 (file)
@@ -16,6 +16,10 @@ mp_err s_mp_mul_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
    mp_word r;
    mp_digit tmpx, *tmpt, *tmpy;
 
+   if (digs < 0) {
+      return MP_VAL;
+   }
+
    /* can we use the fast multiplier? */
    if ((digs < MP_WARRAY) &&
        (MP_MIN(a->used, b->used) < MP_MAXFAST)) {
index b2a287b027b6a11708540944c22c592e009f6623..3c4176a879038b0e97b10fd9a26b2ffa347f2c56 100644 (file)
@@ -26,6 +26,10 @@ mp_err s_mp_mul_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int digs)
    mp_digit W[MP_WARRAY];
    mp_word  _W;
 
+   if (digs < 0) {
+      return MP_VAL;
+   }
+
    /* grow the destination as required */
    if (c->alloc < digs) {
       if ((err = mp_grow(c, digs)) != MP_OKAY) {
index 2bb2a50985f8e17e461bc188b448f617718bc197..c9dd355f83f4e2bdc5f4a62fbaa5a0968d8e37a6 100644 (file)
@@ -15,6 +15,10 @@ mp_err s_mp_mul_high_digs(const mp_int *a, const mp_int *b, mp_int *c, int digs)
    mp_word  r;
    mp_digit tmpx, *tmpt, *tmpy;
 
+   if (digs < 0) {
+      return MP_VAL;
+   }
+
    /* can we use the fast multiplier? */
    if (MP_HAS(S_MP_MUL_HIGH_DIGS_FAST)
        && ((a->used + b->used + 1) < MP_WARRAY)
index a2c4fb6924a29f5528564ba4c7e80b26b0702277..4ce7f590ce8a5aa782f032cbbf7ca4ed4cb2a1d0 100644 (file)
@@ -19,6 +19,10 @@ mp_err s_mp_mul_high_digs_fast(const mp_int *a, const mp_int *b, mp_int *c, int
    mp_digit W[MP_WARRAY];
    mp_word  _W;
 
+   if (digs < 0) {
+      return MP_VAL;
+   }
+
    /* grow the destination as required */
    pa = a->used + b->used;
    if (c->alloc < pa) {
index e5d23711a2c82c11473ddccb8587809f88826792..8900df3e09ef3e3eeb98b02a1da17b758919aa50 100644 (file)
@@ -79,6 +79,9 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK };
 #define HDB_F_GET_FAST_COOKIE  0x20000 /* fetch the FX-COOKIE key (not a normal principal) */
 #define HDB_F_ARMOR_PRINCIPAL  0x40000 /* fetch is for the client of an armor ticket */
 #define HDB_F_USER2USER_PRINCIPAL      0x80000 /* fetch is for the server of a user2user tgs-req */
+#define HDB_F_CROSS_REALM_PRINCIPAL    0x100000 /* fetch is cross-realm ticket */
+#define HDB_F_S4U2SELF_PRINCIPAL       0x200000 /* fetch is for S4U2Self */
+#define HDB_F_S4U2PROXY_PRINCIPAL      0x400000 /* fetch is for S4U2Proxy */
 
 /* hdb_capability_flags */
 #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1
@@ -290,7 +293,18 @@ typedef struct HDB {
     /**
      * Check if resource-based constrained delegation (RBCD) is allowed.
      */
-    krb5_error_code (*hdb_check_rbcd)(krb5_context, struct HDB *, const hdb_entry *, const hdb_entry *, const hdb_entry *, const hdb_entry *, krb5_const_principal, krb5_const_pac, krb5_const_pac, const hdb_entry *);
+    krb5_error_code (*hdb_check_rbcd)(krb5_context context,
+                                     struct HDB *clientdb,
+                                     const hdb_entry *client_krbtgt,
+                                     krb5_const_principal client_principal,
+                                     const hdb_entry *client,
+                                     const hdb_entry *device_krbtgt,
+                                     krb5_const_principal device_principal,
+                                     const hdb_entry *device,
+                                     krb5_const_principal s4u_principal,
+                                     krb5_const_pac client_pac,
+                                     krb5_const_pac device_pac,
+                                     const hdb_entry *target);
 
     /**
      * Check if this name is an alias for the supplied client for PKINIT userPrinicpalName logins
@@ -311,7 +325,7 @@ typedef struct HDB {
     krb5_error_code (*hdb_set_sync)(krb5_context, struct HDB *, int);
 }HDB;
 
-#define HDB_INTERFACE_VERSION  11
+#define HDB_INTERFACE_VERSION  12
 
 struct hdb_method {
     HEIM_PLUGIN_FTABLE_COMMON_ELEMENTS(krb5_context);
index 4026ed6232769de914f2d552181463689307cf22..858398f29d98d57fed758f042020595e5b0c38e6 100644 (file)
@@ -271,7 +271,7 @@ make_fast_ap_fxarmor(krb5_context context,
        if (ret)
            goto out;
 
-       ret = copy_KrbFastArmor(fxarmor, &msg.armor);
+       ret = copy_KrbFastArmor(&msg.armor, fxarmor);
        if (ret) {
            free_KERB_ARMOR_SERVICE_REPLY(&msg);
            goto out;
index 9fed685d639c21bd512dd7dd1d66bd23742b92b0..1c32389fac4a246703eb78154b4fbcb45ca1d0f0 100644 (file)
@@ -983,6 +983,17 @@ fcc_get_first(krb5_context context,
     return 0;
 }
 
+/*
+ * Return true if cred is a removed entry.  We assume that any active entry
+ * with endtime=0 (such as a config entry or gssproxy encrypted credential)
+ * will also have authtime=0.
+ */
+static inline krb5_boolean
+cred_removed(krb5_creds *c)
+{
+    return c->times.endtime == 0 && c->times.authtime != 0;
+}
+
 static krb5_error_code KRB5_CALLCONV
 fcc_get_next (krb5_context context,
              krb5_ccache id,
@@ -997,15 +1008,25 @@ fcc_get_next (krb5_context context,
     if (FCC_CURSOR(*cursor) == NULL)
         return krb5_einval(context, 3);
 
-    FCC_CURSOR(*cursor)->cred_start =
-        krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
+    while (1) {
+       FCC_CURSOR(*cursor)->cred_start =
+           krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
 
-    ret = krb5_ret_creds(FCC_CURSOR(*cursor)->sp, creds);
-    if (ret)
-       krb5_clear_error_message(context);
+       ret = krb5_ret_creds(FCC_CURSOR(*cursor)->sp, creds);
 
-    FCC_CURSOR(*cursor)->cred_end =
-        krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
+       FCC_CURSOR(*cursor)->cred_end =
+           krb5_storage_seek(FCC_CURSOR(*cursor)->sp, 0, SEEK_CUR);
+
+       if (ret) {
+           krb5_clear_error_message(context);
+           break;
+       }
+
+       if (!cred_removed(creds))
+           break;
+
+       krb5_free_cred_contents(context, creds);
+    }
 
     return ret;
 }
@@ -1078,6 +1099,9 @@ cred_delete(krb5_context context,
      */
     cred->times.endtime = 0;
 
+    /* For compatibility with MIT d3b39a8bac6206b5ea78b0bf6a2958c1df0b0dd5 */
+    cred->times.authtime = -1;
+
     /* ...except for config creds because we don't check their endtimes */
     if (srealm && strcmp(srealm, "X-CACHECONF:") == 0) {
        ret = krb5_principal_set_realm(context, cred->server, "X-RMED-CONF:");
index ac218576a55657767b0c96f115d2abcccad09fb6..12f05394a4b6f8e884435b04095e338ccbc2e4c1 100644 (file)
@@ -49,12 +49,22 @@ string_to_proto(const char *string)
     return -1;
 }
 
+#define YOUR_DNS_NEEDS_IMM_ATTENTION "your-dns-needs-immediate-attention."
 static int
 is_invalid_tld_srv_target(const char *target)
 {
-    return (strncmp("your-dns-needs-immediate-attention.",
-                   target, 35) == 0
-           && strchr(&target[35], '.') == NULL);
+    if (strncmp(YOUR_DNS_NEEDS_IMM_ATTENTION, target,
+                sizeof(YOUR_DNS_NEEDS_IMM_ATTENTION) - 1) != 0)
+        return 0;
+    target += sizeof(YOUR_DNS_NEEDS_IMM_ATTENTION) - 1;
+    if (target[0] == '\0' || target[0] == '.')
+        return 0; /* malformed; should be followed by a TLD */
+    target = strchr(target, '.');
+    if (target == NULL)
+        return 0; /* malformed; should end in a '.' */
+    if (target[1] != '\0')
+        return 0; /* malformed; should be followed by just one label (the TLD) */
+    return 1;
 }
 
 /*
@@ -138,28 +148,25 @@ srv_find_realm(krb5_context context, krb5_krbhst_info ***res, int *count,
        if(rr->type == rk_ns_t_srv) {
            krb5_krbhst_info *hi = NULL;
            size_t len;
-           int invalid_tld = 1;
 
            /* Test for top-level domain controlled interruptions */
-           if (!is_invalid_tld_srv_target(rr->u.srv->target)) {
-               invalid_tld = 0;
-               len = strlen(rr->u.srv->target);
-               hi = calloc(1, sizeof(*hi) + len);
+           if (is_invalid_tld_srv_target(rr->u.srv->target)) {
+                krb5_warnx(context,
+                           "Domain lookup failed: "
+                           "Realm %s needs immediate attention "
+                           "see https://icann.org/namecollision",
+                           realm);
+                return KRB5_KDC_UNREACH;
            }
+
+            len = strlen(rr->u.srv->target);
+            hi = calloc(1, sizeof(*hi) + len);
            if(hi == NULL) {
                rk_dns_free_data(r);
                while(--num_srv >= 0)
                    free((*res)[num_srv]);
                free(*res);
                *res = NULL;
-               if (invalid_tld) {
-                   krb5_warnx(context,
-                              "Domain lookup failed: "
-                              "Realm %s needs immediate attention "
-                              "see https://icann.org/namecollision",
-                              realm);
-                   return KRB5_KDC_UNREACH;
-               }
                return krb5_enomem(context);
            }
            (*res)[num_srv++] = hi;
index 474ba5d591d6e94c54c4672521f990fa7397c4cd..cb727c15dbe96c3eba1398c807954677de5a374d 100644 (file)
 
 #ifdef HEIM_WEAK_CRYPTO
 
+#if !defined(HAVE_CRYPT)
+# undef ENABLE_AFS_STRING_TO_KEY
+#endif
+
 #ifdef ENABLE_AFS_STRING_TO_KEY
 
 /* This defines the Andrew string_to_key function.  It accepts a password
index c7b2b763a01e2235d2c96591fac831c88da56b3e..036359c1db197c4eaddeef47cc1b7033bc1a483d 100644 (file)
@@ -38,10 +38,13 @@ RCSID("$Id$");
 
 #include "otp_locl.h"
 
-#if !defined(HAVE_NDBM) && !defined(HAVE_DB_NDBM)
-#include "ndbm_wrap.h"
+#if defined(HAVE_DB_NDBM)
+# include <ndbm.h>
+#elif !defined(HAVE_NDBM)
+# include "ndbm_wrap.h"
 #endif
 
+
 #define RETRIES 5
 
 void *