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