155682Smarkm/* 2233294Sstas * Copyright (c) 1999 - 2001 Kungliga Tekniska H��gskolan 3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden). 4233294Sstas * All rights reserved. 555682Smarkm * 6233294Sstas * Redistribution and use in source and binary forms, with or without 7233294Sstas * modification, are permitted provided that the following conditions 8233294Sstas * are met: 955682Smarkm * 10233294Sstas * 1. Redistributions of source code must retain the above copyright 11233294Sstas * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright 14233294Sstas * notice, this list of conditions and the following disclaimer in the 15233294Sstas * documentation and/or other materials provided with the distribution. 1655682Smarkm * 17233294Sstas * 3. Neither the name of the Institute nor the names of its contributors 18233294Sstas * may be used to endorse or promote products derived from this software 19233294Sstas * without specific prior written permission. 2055682Smarkm * 21233294Sstas * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 22233294Sstas * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23233294Sstas * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24233294Sstas * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 25233294Sstas * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26233294Sstas * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27233294Sstas * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28233294Sstas * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29233294Sstas * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30233294Sstas * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31233294Sstas * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682Smarkm 3655682Smarkmstatic krb5_error_code 3755682Smarkmcopy_hostname(krb5_context context, 3855682Smarkm const char *orig_hostname, 3955682Smarkm char **new_hostname) 4055682Smarkm{ 4155682Smarkm *new_hostname = strdup (orig_hostname); 4278527Sassar if (*new_hostname == NULL) { 43233294Sstas krb5_set_error_message(context, ENOMEM, 44233294Sstas N_("malloc: out of memory", "")); 4555682Smarkm return ENOMEM; 4678527Sassar } 4757416Smarkm strlwr (*new_hostname); 4855682Smarkm return 0; 4955682Smarkm} 5055682Smarkm 51233294Sstas/** 52233294Sstas * krb5_expand_hostname() tries to make orig_hostname into a more 53233294Sstas * canonical one in the newly allocated space returned in 54233294Sstas * new_hostname. 55233294Sstas 56233294Sstas * @param context a Keberos context 57233294Sstas * @param orig_hostname hostname to canonicalise. 58233294Sstas * @param new_hostname output hostname, caller must free hostname with 59233294Sstas * krb5_xfree(). 60233294Sstas * 61233294Sstas * @return Return an error code or 0, see krb5_get_error_message(). 62233294Sstas * 63233294Sstas * @ingroup krb5_support 6455682Smarkm */ 6555682Smarkm 66233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 6755682Smarkmkrb5_expand_hostname (krb5_context context, 6855682Smarkm const char *orig_hostname, 6955682Smarkm char **new_hostname) 7055682Smarkm{ 7155682Smarkm struct addrinfo *ai, *a, hints; 7255682Smarkm int error; 7355682Smarkm 74178825Sdfr if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) 75178825Sdfr return copy_hostname (context, orig_hostname, new_hostname); 76178825Sdfr 7755682Smarkm memset (&hints, 0, sizeof(hints)); 7855682Smarkm hints.ai_flags = AI_CANONNAME; 7955682Smarkm 8055682Smarkm error = getaddrinfo (orig_hostname, NULL, &hints, &ai); 8155682Smarkm if (error) 8255682Smarkm return copy_hostname (context, orig_hostname, new_hostname); 8355682Smarkm for (a = ai; a != NULL; a = a->ai_next) { 8455682Smarkm if (a->ai_canonname != NULL) { 8555682Smarkm *new_hostname = strdup (a->ai_canonname); 8655682Smarkm freeaddrinfo (ai); 8778527Sassar if (*new_hostname == NULL) { 88233294Sstas krb5_set_error_message(context, ENOMEM, 89233294Sstas N_("malloc: out of memory", "")); 9055682Smarkm return ENOMEM; 9178527Sassar } else { 9255682Smarkm return 0; 9378527Sassar } 9455682Smarkm } 9555682Smarkm } 9655682Smarkm freeaddrinfo (ai); 9755682Smarkm return copy_hostname (context, orig_hostname, new_hostname); 9855682Smarkm} 9957416Smarkm 10057416Smarkm/* 10157422Smarkm * handle the case of the hostname being unresolvable and thus identical 10257422Smarkm */ 10357422Smarkm 10457422Smarkmstatic krb5_error_code 10557422Smarkmvanilla_hostname (krb5_context context, 10657422Smarkm const char *orig_hostname, 10757422Smarkm char **new_hostname, 10857422Smarkm char ***realms) 10957422Smarkm{ 11057422Smarkm krb5_error_code ret; 11157422Smarkm 11257422Smarkm ret = copy_hostname (context, orig_hostname, new_hostname); 11357422Smarkm if (ret) 11457422Smarkm return ret; 11557422Smarkm strlwr (*new_hostname); 11657422Smarkm 11757422Smarkm ret = krb5_get_host_realm (context, *new_hostname, realms); 11857422Smarkm if (ret) { 11957422Smarkm free (*new_hostname); 12057422Smarkm return ret; 12157422Smarkm } 12257422Smarkm return 0; 12357422Smarkm} 12457422Smarkm 125233294Sstas/** 126233294Sstas * krb5_expand_hostname_realms() expands orig_hostname to a name we 127233294Sstas * believe to be a hostname in newly allocated space in new_hostname 128233294Sstas * and return the realms new_hostname is believed to belong to in 129233294Sstas * realms. 130233294Sstas * 131233294Sstas * @param context a Keberos context 132233294Sstas * @param orig_hostname hostname to canonicalise. 133233294Sstas * @param new_hostname output hostname, caller must free hostname with 134233294Sstas * krb5_xfree(). 135233294Sstas * @param realms output possible realms, is an array that is terminated 136233294Sstas * with NULL. Caller must free with krb5_free_host_realm(). 137233294Sstas * 138233294Sstas * @return Return an error code or 0, see krb5_get_error_message(). 139233294Sstas * 140233294Sstas * @ingroup krb5_support 14157416Smarkm */ 14257416Smarkm 143233294SstasKRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL 14457416Smarkmkrb5_expand_hostname_realms (krb5_context context, 14557416Smarkm const char *orig_hostname, 14657416Smarkm char **new_hostname, 14757416Smarkm char ***realms) 14857416Smarkm{ 14957416Smarkm struct addrinfo *ai, *a, hints; 15057416Smarkm int error; 15157416Smarkm krb5_error_code ret = 0; 15257416Smarkm 153178825Sdfr if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) 154178825Sdfr return vanilla_hostname (context, orig_hostname, new_hostname, 155178825Sdfr realms); 156178825Sdfr 15757416Smarkm memset (&hints, 0, sizeof(hints)); 15857416Smarkm hints.ai_flags = AI_CANONNAME; 15957416Smarkm 16057416Smarkm error = getaddrinfo (orig_hostname, NULL, &hints, &ai); 16157416Smarkm if (error) 16257422Smarkm return vanilla_hostname (context, orig_hostname, new_hostname, 16357422Smarkm realms); 16457422Smarkm 16557416Smarkm for (a = ai; a != NULL; a = a->ai_next) { 16657416Smarkm if (a->ai_canonname != NULL) { 16772445Sassar ret = copy_hostname (context, a->ai_canonname, new_hostname); 16857422Smarkm if (ret) { 16957422Smarkm freeaddrinfo (ai); 17057422Smarkm return ret; 17157422Smarkm } 17257416Smarkm strlwr (*new_hostname); 17357416Smarkm ret = krb5_get_host_realm (context, *new_hostname, realms); 17457422Smarkm if (ret == 0) { 17557422Smarkm freeaddrinfo (ai); 17657422Smarkm return 0; 17757422Smarkm } 17857416Smarkm free (*new_hostname); 17957416Smarkm } 18057416Smarkm } 18190926Snectar freeaddrinfo(ai); 18257422Smarkm return vanilla_hostname (context, orig_hostname, new_hostname, realms); 18357416Smarkm} 184