~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to source4/heimdal/lib/krb5/expand_hostname.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 1999 - 2001 Kungliga Tekniska Högskolan
 
3
 * (Royal Institute of Technology, Stockholm, Sweden).
 
4
 * All rights reserved.
 
5
 *
 
6
 * Redistribution and use in source and binary forms, with or without
 
7
 * modification, are permitted provided that the following conditions
 
8
 * are met:
 
9
 *
 
10
 * 1. Redistributions of source code must retain the above copyright
 
11
 *    notice, this list of conditions and the following disclaimer.
 
12
 *
 
13
 * 2. Redistributions in binary form must reproduce the above copyright
 
14
 *    notice, this list of conditions and the following disclaimer in the
 
15
 *    documentation and/or other materials provided with the distribution.
 
16
 *
 
17
 * 3. Neither the name of the Institute nor the names of its contributors
 
18
 *    may be used to endorse or promote products derived from this software
 
19
 *    without specific prior written permission.
 
20
 *
 
21
 * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
 
22
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 
23
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 
24
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
 
25
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 
26
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 
27
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
28
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 
29
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 
30
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 
31
 * SUCH DAMAGE.
 
32
 */
 
33
 
 
34
#include "krb5_locl.h"
 
35
 
 
36
RCSID("$Id$");
 
37
 
 
38
static krb5_error_code
 
39
copy_hostname(krb5_context context,
 
40
              const char *orig_hostname,
 
41
              char **new_hostname)
 
42
{
 
43
    *new_hostname = strdup (orig_hostname);
 
44
    if (*new_hostname == NULL) {
 
45
        krb5_set_error_message(context, ENOMEM,
 
46
                               N_("malloc: out of memory", ""));
 
47
        return ENOMEM;
 
48
    }
 
49
    strlwr (*new_hostname);
 
50
    return 0;
 
51
}
 
52
 
 
53
/*
 
54
 * Try to make `orig_hostname' into a more canonical one in the newly
 
55
 * allocated space returned in `new_hostname'.
 
56
 */
 
57
 
 
58
krb5_error_code KRB5_LIB_FUNCTION
 
59
krb5_expand_hostname (krb5_context context,
 
60
                      const char *orig_hostname,
 
61
                      char **new_hostname)
 
62
{
 
63
    struct addrinfo *ai, *a, hints;
 
64
    int error;
 
65
 
 
66
    if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
 
67
        return copy_hostname (context, orig_hostname, new_hostname);
 
68
 
 
69
    memset (&hints, 0, sizeof(hints));
 
70
    hints.ai_flags = AI_CANONNAME;
 
71
 
 
72
    error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
 
73
    if (error)
 
74
        return copy_hostname (context, orig_hostname, new_hostname);
 
75
    for (a = ai; a != NULL; a = a->ai_next) {
 
76
        if (a->ai_canonname != NULL) {
 
77
            *new_hostname = strdup (a->ai_canonname);
 
78
            freeaddrinfo (ai);
 
79
            if (*new_hostname == NULL) {
 
80
                krb5_set_error_message(context, ENOMEM,
 
81
                                       N_("malloc: out of memory", ""));
 
82
                return ENOMEM;
 
83
            } else {
 
84
                return 0;
 
85
            }
 
86
        }
 
87
    }
 
88
    freeaddrinfo (ai);
 
89
    return copy_hostname (context, orig_hostname, new_hostname);
 
90
}
 
91
 
 
92
/*
 
93
 * handle the case of the hostname being unresolvable and thus identical
 
94
 */
 
95
 
 
96
static krb5_error_code
 
97
vanilla_hostname (krb5_context context,
 
98
                  const char *orig_hostname,
 
99
                  char **new_hostname,
 
100
                  char ***realms)
 
101
{
 
102
    krb5_error_code ret;
 
103
 
 
104
    ret = copy_hostname (context, orig_hostname, new_hostname);
 
105
    if (ret)
 
106
        return ret;
 
107
    strlwr (*new_hostname);
 
108
 
 
109
    ret = krb5_get_host_realm (context, *new_hostname, realms);
 
110
    if (ret) {
 
111
        free (*new_hostname);
 
112
        return ret;
 
113
    }
 
114
    return 0;
 
115
}
 
116
 
 
117
/*
 
118
 * expand `hostname' to a name we believe to be a hostname in newly
 
119
 * allocated space in `host' and return realms in `realms'.
 
120
 */
 
121
 
 
122
krb5_error_code KRB5_LIB_FUNCTION
 
123
krb5_expand_hostname_realms (krb5_context context,
 
124
                             const char *orig_hostname,
 
125
                             char **new_hostname,
 
126
                             char ***realms)
 
127
{
 
128
    struct addrinfo *ai, *a, hints;
 
129
    int error;
 
130
    krb5_error_code ret = 0;
 
131
 
 
132
    if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
 
133
        return vanilla_hostname (context, orig_hostname, new_hostname,
 
134
                                 realms);
 
135
 
 
136
    memset (&hints, 0, sizeof(hints));
 
137
    hints.ai_flags = AI_CANONNAME;
 
138
 
 
139
    error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
 
140
    if (error)
 
141
        return vanilla_hostname (context, orig_hostname, new_hostname,
 
142
                                 realms);
 
143
 
 
144
    for (a = ai; a != NULL; a = a->ai_next) {
 
145
        if (a->ai_canonname != NULL) {
 
146
            ret = copy_hostname (context, a->ai_canonname, new_hostname);
 
147
            if (ret) {
 
148
                freeaddrinfo (ai);
 
149
                return ret;
 
150
            }
 
151
            strlwr (*new_hostname);
 
152
            ret = krb5_get_host_realm (context, *new_hostname, realms);
 
153
            if (ret == 0) {
 
154
                freeaddrinfo (ai);
 
155
                return 0;
 
156
            }
 
157
            free (*new_hostname);
 
158
        }
 
159
    }
 
160
    freeaddrinfo(ai);
 
161
    return vanilla_hostname (context, orig_hostname, new_hostname, realms);
 
162
}