155682Smarkm/* 278527Sassar * Copyright (c) 1999 - 2001 Kungliga Tekniska H�gskolan 355682Smarkm * (Royal Institute of Technology, Stockholm, Sweden). 455682Smarkm * All rights reserved. 555682Smarkm * 655682Smarkm * Redistribution and use in source and binary forms, with or without 755682Smarkm * modification, are permitted provided that the following conditions 855682Smarkm * are met: 955682Smarkm * 1055682Smarkm * 1. Redistributions of source code must retain the above copyright 1155682Smarkm * notice, this list of conditions and the following disclaimer. 1255682Smarkm * 1355682Smarkm * 2. Redistributions in binary form must reproduce the above copyright 1455682Smarkm * notice, this list of conditions and the following disclaimer in the 1555682Smarkm * documentation and/or other materials provided with the distribution. 1655682Smarkm * 1755682Smarkm * 3. Neither the name of the Institute nor the names of its contributors 1855682Smarkm * may be used to endorse or promote products derived from this software 1955682Smarkm * without specific prior written permission. 2055682Smarkm * 2155682Smarkm * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND 2255682Smarkm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2355682Smarkm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2455682Smarkm * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE 2555682Smarkm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2655682Smarkm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2755682Smarkm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2855682Smarkm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2955682Smarkm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3055682Smarkm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3155682Smarkm * SUCH DAMAGE. 3255682Smarkm */ 3355682Smarkm 3455682Smarkm#include "krb5_locl.h" 3555682Smarkm 36178825SdfrRCSID("$Id: expand_hostname.c 22229 2007-12-08 21:40:59Z lha $"); 3755682Smarkm 3855682Smarkmstatic krb5_error_code 3955682Smarkmcopy_hostname(krb5_context context, 4055682Smarkm const char *orig_hostname, 4155682Smarkm char **new_hostname) 4255682Smarkm{ 4355682Smarkm *new_hostname = strdup (orig_hostname); 4478527Sassar if (*new_hostname == NULL) { 4578527Sassar krb5_set_error_string(context, "malloc: out of memory"); 4655682Smarkm return ENOMEM; 4778527Sassar } 4857416Smarkm strlwr (*new_hostname); 4955682Smarkm return 0; 5055682Smarkm} 5155682Smarkm 5255682Smarkm/* 5355682Smarkm * Try to make `orig_hostname' into a more canonical one in the newly 5455682Smarkm * allocated space returned in `new_hostname'. 5555682Smarkm */ 5655682Smarkm 57178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 5855682Smarkmkrb5_expand_hostname (krb5_context context, 5955682Smarkm const char *orig_hostname, 6055682Smarkm char **new_hostname) 6155682Smarkm{ 6255682Smarkm struct addrinfo *ai, *a, hints; 6355682Smarkm int error; 6455682Smarkm 65178825Sdfr if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) 66178825Sdfr return copy_hostname (context, orig_hostname, new_hostname); 67178825Sdfr 6855682Smarkm memset (&hints, 0, sizeof(hints)); 6955682Smarkm hints.ai_flags = AI_CANONNAME; 7055682Smarkm 7155682Smarkm error = getaddrinfo (orig_hostname, NULL, &hints, &ai); 7255682Smarkm if (error) 7355682Smarkm return copy_hostname (context, orig_hostname, new_hostname); 7455682Smarkm for (a = ai; a != NULL; a = a->ai_next) { 7555682Smarkm if (a->ai_canonname != NULL) { 7655682Smarkm *new_hostname = strdup (a->ai_canonname); 7755682Smarkm freeaddrinfo (ai); 7878527Sassar if (*new_hostname == NULL) { 7978527Sassar krb5_set_error_string(context, "malloc: out of memory"); 8055682Smarkm return ENOMEM; 8178527Sassar } else { 8255682Smarkm return 0; 8378527Sassar } 8455682Smarkm } 8555682Smarkm } 8655682Smarkm freeaddrinfo (ai); 8755682Smarkm return copy_hostname (context, orig_hostname, new_hostname); 8855682Smarkm} 8957416Smarkm 9057416Smarkm/* 9157422Smarkm * handle the case of the hostname being unresolvable and thus identical 9257422Smarkm */ 9357422Smarkm 9457422Smarkmstatic krb5_error_code 9557422Smarkmvanilla_hostname (krb5_context context, 9657422Smarkm const char *orig_hostname, 9757422Smarkm char **new_hostname, 9857422Smarkm char ***realms) 9957422Smarkm{ 10057422Smarkm krb5_error_code ret; 10157422Smarkm 10257422Smarkm ret = copy_hostname (context, orig_hostname, new_hostname); 10357422Smarkm if (ret) 10457422Smarkm return ret; 10557422Smarkm strlwr (*new_hostname); 10657422Smarkm 10757422Smarkm ret = krb5_get_host_realm (context, *new_hostname, realms); 10857422Smarkm if (ret) { 10957422Smarkm free (*new_hostname); 11057422Smarkm return ret; 11157422Smarkm } 11257422Smarkm return 0; 11357422Smarkm} 11457422Smarkm 11557422Smarkm/* 11657416Smarkm * expand `hostname' to a name we believe to be a hostname in newly 11757416Smarkm * allocated space in `host' and return realms in `realms'. 11857416Smarkm */ 11957416Smarkm 120178825Sdfrkrb5_error_code KRB5_LIB_FUNCTION 12157416Smarkmkrb5_expand_hostname_realms (krb5_context context, 12257416Smarkm const char *orig_hostname, 12357416Smarkm char **new_hostname, 12457416Smarkm char ***realms) 12557416Smarkm{ 12657416Smarkm struct addrinfo *ai, *a, hints; 12757416Smarkm int error; 12857416Smarkm krb5_error_code ret = 0; 12957416Smarkm 130178825Sdfr if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0) 131178825Sdfr return vanilla_hostname (context, orig_hostname, new_hostname, 132178825Sdfr realms); 133178825Sdfr 13457416Smarkm memset (&hints, 0, sizeof(hints)); 13557416Smarkm hints.ai_flags = AI_CANONNAME; 13657416Smarkm 13757416Smarkm error = getaddrinfo (orig_hostname, NULL, &hints, &ai); 13857416Smarkm if (error) 13957422Smarkm return vanilla_hostname (context, orig_hostname, new_hostname, 14057422Smarkm realms); 14157422Smarkm 14257416Smarkm for (a = ai; a != NULL; a = a->ai_next) { 14357416Smarkm if (a->ai_canonname != NULL) { 14472445Sassar ret = copy_hostname (context, a->ai_canonname, new_hostname); 14557422Smarkm if (ret) { 14657422Smarkm freeaddrinfo (ai); 14757422Smarkm return ret; 14857422Smarkm } 14957416Smarkm strlwr (*new_hostname); 15057416Smarkm ret = krb5_get_host_realm (context, *new_hostname, realms); 15157422Smarkm if (ret == 0) { 15257422Smarkm freeaddrinfo (ai); 15357422Smarkm return 0; 15457422Smarkm } 15557416Smarkm free (*new_hostname); 15657416Smarkm } 15757416Smarkm } 15890926Snectar freeaddrinfo(ai); 15957422Smarkm return vanilla_hostname (context, orig_hostname, new_hostname, realms); 16057416Smarkm} 161