summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2013-12-08 18:05:26 -0500
committerGreg Hudson <ghudson@mit.edu>2013-12-11 23:56:35 -0500
commit23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65 (patch)
tree335a99fd3a955786926f1467a3a3c362e0fa6572
parent1f728b9333401fd4b8c8a9bbb63cb125d53cd5c8 (diff)
downloadkrb5-23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65.tar.gz
krb5-23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65.tar.xz
krb5-23a2a3d2f2c5f3ba3393aeca4908d2b2cb0bbe65.zip
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)
-rw-r--r--src/lib/krb5/os/sn2princ.c39
1 files changed, 37 insertions, 2 deletions
diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c
index c9b3c8276b..92969cd413 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;
}