krb5 commit: Allow ":port" suffixes in sn2princ hostnames

Greg Hudson ghudson at MIT.EDU
Thu Dec 12 00:17:08 EST 2013


https://github.com/krb5/krb5/commit/23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65
commit 23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65
Author: Greg Hudson <ghudson at mit.edu>
Date:   Sun Dec 8 18:05:26 2013 -0500

    Allow ":port" suffixes in sn2princ hostnames
    
    MSSQLSvc principal names can contain a ":port" or ":instance" trailer
    on the hostname part.  If we see that in the hostname argument of
    krb5_sname_to_principal(), remove it before canonicalizing the
    hostname and put it back on afterwards.
    
    ticket: 7795 (new)

 src/lib/krb5/os/sn2princ.c |   39 +++++++++++++++++++++++++++++++++++++--
 1 files changed, 37 insertions(+), 2 deletions(-)

diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
index c9b3c82..92969cd 100644
--- a/src/lib/krb5/os/sn2princ.c
+++ b/src/lib/krb5/os/sn2princ.c
@@ -116,6 +116,20 @@ cleanup:
     return (*canonhost_out == NULL) ? ENOMEM : 0;
 }
 
+/* If hostname appears to have a :port or :instance trailer (used in MSSQLSvc
+ * principals), return a pointer to the separator.  Otherwise return NULL. */
+static const char *
+find_trailer(const char *hostname)
+{
+    const char *p = strchr(hostname, ':');
+
+    /* Look for a single colon followed by one or more characters.  An IPv6
+     * address will have more than one colon, so don't accept that. */
+    if (p == NULL || p[1] == '\0' || strchr(p + 1, ':') != NULL)
+        return NULL;
+    return p;
+}
+
 krb5_error_code KRB5_CALLCONV
 krb5_sname_to_principal(krb5_context context, const char *hostname,
                         const char *sname, krb5_int32 type,
@@ -123,8 +137,9 @@ krb5_sname_to_principal(krb5_context context, const char *hostname,
 {
     krb5_error_code ret;
     krb5_principal princ;
-    const char *realm;
-    char **hrealms = NULL, *canonhost = NULL, localname[MAXHOSTNAMELEN];
+    const char *realm, *trailer;
+    char **hrealms = NULL, *canonhost = NULL, *hostonly = NULL, *concat = NULL;
+    char localname[MAXHOSTNAMELEN];
 
     *princ_out = NULL;
 
@@ -142,6 +157,15 @@ krb5_sname_to_principal(krb5_context context, const char *hostname,
     if (sname == NULL)
         sname = "host";
 
+    /* If there is a trailer, remove it for now. */
+    trailer = find_trailer(hostname);
+    if (trailer != NULL) {
+        hostonly = k5memdup0(hostname, trailer - hostname, &ret);
+        if (hostonly == NULL)
+            goto cleanup;
+        hostname = hostonly;
+    }
+
     /* Canonicalize the hostname if appropriate. */
     ret = canon_hostname(context, type, hostname, &canonhost);
     if (ret)
@@ -158,6 +182,15 @@ krb5_sname_to_principal(krb5_context context, const char *hostname,
     }
     realm = hrealms[0];
 
+    /* If there was a trailer, put it back on the end. */
+    if (trailer != NULL) {
+        if (asprintf(&concat, "%s%s", hostname, trailer) < 0) {
+            ret = ENOMEM;
+            goto cleanup;
+        }
+        hostname = concat;
+    }
+
     ret = krb5_build_principal(context, &princ, strlen(realm), realm, sname,
                                hostname, (char *)NULL);
     if (ret)
@@ -167,7 +200,9 @@ krb5_sname_to_principal(krb5_context context, const char *hostname,
     *princ_out = princ;
 
 cleanup:
+    free(hostonly);
     free(canonhost);
+    free(concat);
     krb5_free_host_realm(context, hrealms);
     return ret;
 }


More information about the cvs-krb5 mailing list