From: Greg Hudson Date: Tue, 17 Nov 2015 18:06:31 +0000 (-0500) Subject: Add krb5_expand_hostname() API X-Git-Tag: krb5-1.15-beta1~75 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=faf9ad33e9e6b7ffaac02fcd249e60e2224f5ec7;p=thirdparty%2Fkrb5.git Add krb5_expand_hostname() API Add a new public libkrb5 function expand_hostname(). It follows the same contract as the Heimdal function, except that the caller should use krb5_free_string() instead of krb5_xfree() to free the result. As a small side effect, we no longer remove trailing dots from the hostname in krb5_sname_to_principal() when invoked with type KRB5_NT_UNKNOWN. Adjust a test case in t_sn2princ.py accordingly. ticket: 8278 (new) --- diff --git a/doc/appdev/refs/api/index.rst b/doc/appdev/refs/api/index.rst index 55acaf0e6a..f2f27fe72e 100644 --- a/doc/appdev/refs/api/index.rst +++ b/doc/appdev/refs/api/index.rst @@ -24,6 +24,7 @@ Frequently used public interfaces krb5_cc_resolve.rst krb5_change_password.rst krb5_chpw_message.rst + krb5_expand_hostname.rst krb5_free_context.rst krb5_free_error_message.rst krb5_free_principal.rst diff --git a/src/include/krb5/krb5.hin b/src/include/krb5/krb5.hin index a1bf849668..c8928cbf71 100644 --- a/src/include/krb5/krb5.hin +++ b/src/include/krb5/krb5.hin @@ -4967,6 +4967,23 @@ krb5_set_default_realm(krb5_context context, const char *lrealm); void KRB5_CALLCONV krb5_free_default_realm(krb5_context context, char *lrealm); +/** + * Canonicalize a hostname, possibly using name service. + * + * @param [in] context Library context + * @param [in] host Input hostname + * @param [out] canonhost_out Canonicalized hostname + * + * This function canonicalizes orig_hostname, possibly using name service + * lookups if configuration permits. Use krb5_free_string() to free @a + * canonhost_out when it is no longer needed. + * + * @version New in 1.15 + */ +krb5_error_code KRB5_CALLCONV +krb5_expand_hostname(krb5_context context, const char *host, + char **canonhost_out); + /** * Generate a full principal name from a service name. * diff --git a/src/lib/krb5/libkrb5.exports b/src/lib/krb5/libkrb5.exports index cdda32df28..ed6cad6ad0 100644 --- a/src/lib/krb5/libkrb5.exports +++ b/src/lib/krb5/libkrb5.exports @@ -282,6 +282,7 @@ krb5_encode_authdata_container krb5_encode_kdc_rep krb5_encrypt_helper krb5_encrypt_tkt_part +krb5_expand_hostname krb5_externalize_data krb5_externalize_opaque krb5_fcc_ops diff --git a/src/lib/krb5/os/sn2princ.c b/src/lib/krb5/os/sn2princ.c index 92969cd413..5932fd9b3f 100644 --- a/src/lib/krb5/os/sn2princ.c +++ b/src/lib/krb5/os/sn2princ.c @@ -53,11 +53,9 @@ use_reverse_dns(krb5_context context) return value; } -/* Set *name_out to the canonicalized form of name, obeying relevant - * configuration settings. The caller must free the result. */ -static krb5_error_code -canon_hostname(krb5_context context, krb5_int32 type, const char *host, - char **canonhost_out) +krb5_error_code KRB5_CALLCONV +krb5_expand_hostname(krb5_context context, const char *host, + char **canonhost_out) { struct addrinfo *ai = NULL, hint; char namebuf[NI_MAXHOST], *copy, *p; @@ -67,7 +65,7 @@ canon_hostname(krb5_context context, krb5_int32 type, const char *host, *canonhost_out = NULL; canonhost = host; - if (type == KRB5_NT_SRV_HST && context->dns_canonicalize_hostname) { + if (context->dns_canonicalize_hostname) { /* Try a forward lookup of the hostname. */ memset(&hint, 0, sizeof(hint)); hint.ai_flags = AI_CANONNAME; @@ -92,12 +90,10 @@ canon_hostname(krb5_context context, krb5_int32 type, const char *host, if (copy == NULL) goto cleanup; - if (type == KRB5_NT_SRV_HST) { - /* Convert the hostname to lower case. */ - for (p = copy; *p != '\0'; p++) { - if (isupper((unsigned char)*p)) - *p = tolower((unsigned char)*p); - } + /* Convert the hostname to lower case. */ + for (p = copy; *p != '\0'; p++) { + if (isupper((unsigned char)*p)) + *p = tolower((unsigned char)*p); } /* Remove any trailing dot. */ @@ -167,10 +163,12 @@ krb5_sname_to_principal(krb5_context context, const char *hostname, } /* Canonicalize the hostname if appropriate. */ - ret = canon_hostname(context, type, hostname, &canonhost); - if (ret) - goto cleanup; - hostname = canonhost; + if (type == KRB5_NT_SRV_HST) { + ret = krb5_expand_hostname(context, hostname, &canonhost); + if (ret) + goto cleanup; + hostname = canonhost; + } /* Find the realm of the host. */ ret = krb5_get_host_realm(context, hostname, &hrealms); diff --git a/src/lib/krb5_32.def b/src/lib/krb5_32.def index 3b271d3f1c..e5b560dfcb 100644 --- a/src/lib/krb5_32.def +++ b/src/lib/krb5_32.def @@ -469,3 +469,4 @@ EXPORTS krb5_set_kdc_recv_hook @434 krb5_get_init_creds_opt_set_pac_request @435 krb5int_trace @436 ; PRIVATE GSSAPI + krb5_expand_hostname @437 diff --git a/src/tests/t_sn2princ.py b/src/tests/t_sn2princ.py index 6a349c4097..19a0d2fa76 100755 --- a/src/tests/t_sn2princ.py +++ b/src/tests/t_sn2princ.py @@ -44,11 +44,10 @@ testu('ptr-mismatch.kerberos.org', 'ptr-mismatch.kerberos.org', 'R1') testu('Example.COM', 'Example.COM', 'R2') testu('abcde', 'abcde', '') -# A ':port' or ':instance' trailer should be ignored for hostname -# adjustment and realm lookup. If there is more than one colon in the -# name, we assume it's an IPv6 address and don't treat it as having a -# trailer. -testu('example.com.:123', 'example.com:123', 'R2') +# A ':port' or ':instance' trailer should be ignored for realm lookup. +# If there is more than one colon in the name, we assume it's an IPv6 +# address and don't treat it as having a trailer. +testu('example.com.:123', 'example.com.:123', 'R2') testu('Example.COM:xyZ', 'Example.COM:xyZ', 'R2') testu('example.com.::123', 'example.com.::123', '')