krb5: _krb5_principal_is_anonymous() helper API
authorLuke Howard <lukeh@padl.com>
Sat, 4 May 2019 06:10:13 +0000 (16:10 +1000)
committerJeffrey Altman <jaltman@auristor.com>
Tue, 14 May 2019 19:16:19 +0000 (15:16 -0400)
Add _krb5_principal_is_anonymous() private API for checking if a principal is
anonymous or not. The third argument determines whether to match authenticated
anonymous, unauthenticated anonymous, or both types of principal.

kdc/kerberos5.c
kuser/kinit.c
kuser/kuser_locl.h
lib/krb5/krb5_locl.h
lib/krb5/libkrb5-exports.def.in
lib/krb5/principal.c
lib/krb5/ticket.c
lib/krb5/version-script.map

index 11888804d1861e3b7a124737b0c0a45dd5bce2c3..fd067659c0ef22b83773295d669b3b71cfefc383 100644 (file)
@@ -1613,13 +1613,7 @@ generate_pac(kdc_request_t r, Key *skey)
 krb5_boolean
 _kdc_is_anonymous(krb5_context context, krb5_const_principal principal)
 {
-    if ((principal->name.name_type != KRB5_NT_WELLKNOWN &&
-        principal->name.name_type != KRB5_NT_UNKNOWN) ||
-       principal->name.name_string.len != 2 ||
-       strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
-       strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
-       return 0;
-    return 1;
+    return _krb5_principal_is_anonymous(context, principal, KRB5_ANON_MATCH_ANY);
 }
 
 static int
index 8cd5f3aa6653596da114a7ce44e4e07fd3f5d105..8771b1d5470c149afadc248bc6fc69da0ababd8d 100644 (file)
@@ -425,18 +425,6 @@ store_ntlmkey(krb5_context context, krb5_ccache id,
 }
 #endif
 
-static krb5_boolean
-is_anonymous_princ_p(krb5_const_principal principal)
-{
-    if ((principal->name.name_type != KRB5_NT_WELLKNOWN &&
-       principal->name.name_type != KRB5_NT_UNKNOWN) ||
-       principal->name.name_string.len != 2 ||
-       strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
-       strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
-       return 0;
-    return 1;
-}
-
 static krb5_error_code
 get_new_tickets(krb5_context context,
                krb5_principal principal,
@@ -642,7 +630,8 @@ get_new_tickets(krb5_context context,
            krb5_warn(context, ret, "krb5_init_creds_set_keytab");
            goto out;
        }
-    } else if (pk_user_id || ent_user_id || is_anonymous_princ_p(principal)) {
+    } else if (pk_user_id || ent_user_id ||
+              _krb5_principal_is_anonymous(context, principal, KRB5_ANON_MATCH_ANY)) {
 
     } else if (!interactive && passwd[0] == '\0') {
        static int already_warned = 0;
index a0fcc9db698c83e877ed5b13f29b2165c2cf0d2c..36a2161fb555ceb716ea0e10baa6ec7ee99c4ab6 100644 (file)
@@ -72,6 +72,7 @@
 #include <parse_time.h>
 #include <err.h>
 #include <krb5.h>
+#include "krb5_locl.h"
 
 #if defined(HAVE_SYS_IOCTL_H) && SunOS != 40
 #include <sys/ioctl.h>
index 2f6bc55036574e46704351663897749c0d29b6ab..668232d9473e6e64fbe1c6bdae6bb3ea834c91f2 100644 (file)
@@ -402,4 +402,9 @@ struct krb5_plugin_data {
     krb5_get_instance_func_t get_instance;
 };
 
+/* _krb5_principal_is_anonymous() */
+#define KRB5_ANON_MATCH_AUTHENTICATED  1 /* authenticated with anon flag */
+#define KRB5_ANON_MATCH_UNAUTHENTICATED        2 /* anonymous PKINIT */
+#define KRB5_ANON_MATCH_ANY            ( KRB5_ANON_MATCH_AUTHENTICATED | KRB5_ANON_MATCH_UNAUTHENTICATED )
+
 #endif /* __KRB5_LOCL_H__ */
index 79821fa35519c2056aa4de7cdc4b4dbb665e1fc6..4423cfb945da3726b7d7554d7c26534b54a80b0f 100644 (file)
@@ -776,6 +776,7 @@ EXPORTS
        _krb5_pk_octetstring2key
        _krb5_plugin_run_f
        _krb5_enctype_requires_random_salt
+       _krb5_principal_is_anonymous
        _krb5_principal2principalname
        _krb5_principalname2krb5_principal
        _krb5_put_int
index 206cde1d63bc4cb30938ea798cddb7613a8f003a..df9c2316bc49a272037d4f2665e2beccbbaf4686 100644 (file)
@@ -1247,6 +1247,32 @@ krb5_principal_is_root_krbtgt(krb5_context context, krb5_const_principal p)
        strcmp(p->name.name_string.val[1], p->realm) == 0;
 }
 
+/**
+ * Returns true iff name is WELLKNOWN/ANONYMOUS
+ *
+ * @ingroup krb5_principal
+ */
+
+krb5_boolean KRB5_LIB_FUNCTION
+_krb5_principal_is_anonymous(krb5_context context,
+                            krb5_const_principal p,
+                            unsigned int flags)
+{
+    int anon_realm;
+
+    if ((p->name.name_type != KRB5_NT_WELLKNOWN &&
+         p->name.name_type != KRB5_NT_UNKNOWN) ||
+        p->name.name_string.len != 2 ||
+        strcmp(p->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
+        strcmp(p->name.name_string.val[1], KRB5_ANON_NAME) != 0)
+        return FALSE;
+
+    anon_realm = strcmp(p->realm, KRB5_ANON_REALM) == 0;
+
+    return ((flags & KRB5_ANON_MATCH_AUTHENTICATED) && !anon_realm) ||
+          ((flags & KRB5_ANON_MATCH_UNAUTHENTICATED) && anon_realm);
+}
+
 static int
 tolower_ascii(int c)
 {
index c9523bb5648d5fec97affdcffb6d9de9ac824cb9..d514426b75c491beab25171fb3f887dac65eb922 100644 (file)
@@ -527,18 +527,6 @@ noreferral:
 }
 
 
-static krb5_boolean
-is_anonymous_principal(krb5_context context, krb5_const_principal principal)
-{
-    if ((principal->name.name_type != KRB5_NT_WELLKNOWN &&
-         principal->name.name_type != KRB5_NT_UNKNOWN) ||
-        principal->name.name_string.len != 2 ||
-        strcmp(principal->name.name_string.val[0], KRB5_WELLKNOWN_NAME) != 0 ||
-        strcmp(principal->name.name_string.val[1], KRB5_ANON_NAME) != 0)
-        return 0;
-    return 1;
-}
-
 /*
  * Verify returned client principal name in anonymous/referral case
  */
@@ -551,7 +539,7 @@ check_client_mismatch(krb5_context context,
                      krb5_keyblock const * key)
 {
     if (rep->enc_part.flags.anonymous) {
-       if (!is_anonymous_principal(context, mapped)) {
+       if (!_krb5_principal_is_anonymous(context, mapped, KRB5_ANON_MATCH_ANY)) {
            krb5_set_error_message(context, KRB5KRB_AP_ERR_MODIFIED,
                                   N_("Anonymous ticket does not contain anonymous "
                                      "principal", ""));
index a9710a0877464cf587a7324c3b4933c1f58c931c..0b80a151bac8bdeb0586d9ce73b758d62df39305 100644 (file)
@@ -767,6 +767,7 @@ HEIMDAL_KRB5_2.0 {
                _krb5_pk_mk_ContentInfo;
                _krb5_pk_octetstring2key;
                _krb5_plugin_run_f;
+               _krb5_principal_is_anonymous;
                _krb5_principal2principalname;
                _krb5_principalname2krb5_principal;
                _krb5_put_int;