Line data Source code
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 : static krb5_error_code
37 1316 : copy_hostname(krb5_context context,
38 : const char *orig_hostname,
39 : char **new_hostname)
40 : {
41 1316 : *new_hostname = strdup (orig_hostname);
42 1316 : if (*new_hostname == NULL)
43 0 : return krb5_enomem(context);
44 1316 : strlwr (*new_hostname);
45 1316 : return 0;
46 : }
47 :
48 : /**
49 : * krb5_expand_hostname() tries to make orig_hostname into a more
50 : * canonical one in the newly allocated space returned in
51 : * new_hostname.
52 :
53 : * @param context a Keberos context
54 : * @param orig_hostname hostname to canonicalise.
55 : * @param new_hostname output hostname, caller must free hostname with
56 : * krb5_xfree().
57 : *
58 : * @return Return an error code or 0, see krb5_get_error_message().
59 : *
60 : * @ingroup krb5_support
61 : */
62 :
63 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
64 0 : krb5_expand_hostname (krb5_context context,
65 : const char *orig_hostname,
66 : char **new_hostname)
67 : {
68 0 : struct addrinfo *ai, *a, hints;
69 0 : int error;
70 :
71 0 : if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0 ||
72 0 : krb5_config_get_bool(context, NULL, "libdefaults", "block_dns", NULL))
73 0 : return copy_hostname (context, orig_hostname, new_hostname);
74 :
75 0 : memset (&hints, 0, sizeof(hints));
76 0 : hints.ai_flags = AI_CANONNAME;
77 :
78 0 : error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
79 0 : if (error)
80 0 : return copy_hostname (context, orig_hostname, new_hostname);
81 0 : for (a = ai; a != NULL; a = a->ai_next) {
82 0 : if (a->ai_canonname != NULL) {
83 0 : *new_hostname = strdup (a->ai_canonname);
84 0 : freeaddrinfo (ai);
85 0 : if (*new_hostname == NULL)
86 0 : return krb5_enomem(context);
87 : else
88 0 : return 0;
89 : }
90 : }
91 0 : freeaddrinfo (ai);
92 0 : return copy_hostname (context, orig_hostname, new_hostname);
93 : }
94 :
95 : /*
96 : * handle the case of the hostname being unresolvable and thus identical
97 : */
98 :
99 : static krb5_error_code
100 1316 : vanilla_hostname (krb5_context context,
101 : const char *orig_hostname,
102 : char **new_hostname,
103 : char ***realms)
104 : {
105 0 : krb5_error_code ret;
106 :
107 1316 : ret = copy_hostname (context, orig_hostname, new_hostname);
108 1316 : if (ret)
109 0 : return ret;
110 1316 : strlwr (*new_hostname);
111 :
112 1316 : ret = krb5_get_host_realm (context, *new_hostname, realms);
113 1316 : if (ret) {
114 0 : free (*new_hostname);
115 0 : return ret;
116 : }
117 1316 : return 0;
118 : }
119 :
120 : /**
121 : * krb5_expand_hostname_realms() expands orig_hostname to a name we
122 : * believe to be a hostname in newly allocated space in new_hostname
123 : * and return the realms new_hostname is believed to belong to in
124 : * realms.
125 : *
126 : * @param context a Keberos context
127 : * @param orig_hostname hostname to canonicalise.
128 : * @param new_hostname output hostname, caller must free hostname with
129 : * krb5_xfree().
130 : * @param realms output possible realms, is an array that is terminated
131 : * with NULL. Caller must free with krb5_free_host_realm().
132 : *
133 : * @return Return an error code or 0, see krb5_get_error_message().
134 : *
135 : * @ingroup krb5_support
136 : */
137 :
138 : KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
139 1316 : krb5_expand_hostname_realms (krb5_context context,
140 : const char *orig_hostname,
141 : char **new_hostname,
142 : char ***realms)
143 : {
144 0 : struct addrinfo *ai, *a, hints;
145 0 : int error;
146 1316 : krb5_error_code ret = 0;
147 :
148 1316 : if ((context->flags & KRB5_CTX_F_DNS_CANONICALIZE_HOSTNAME) == 0)
149 1316 : return vanilla_hostname (context, orig_hostname, new_hostname,
150 : realms);
151 :
152 0 : memset (&hints, 0, sizeof(hints));
153 0 : hints.ai_flags = AI_CANONNAME;
154 :
155 0 : error = getaddrinfo (orig_hostname, NULL, &hints, &ai);
156 0 : if (error)
157 0 : return vanilla_hostname (context, orig_hostname, new_hostname,
158 : realms);
159 :
160 0 : for (a = ai; a != NULL; a = a->ai_next) {
161 0 : if (a->ai_canonname != NULL) {
162 0 : ret = copy_hostname (context, a->ai_canonname, new_hostname);
163 0 : if (ret) {
164 0 : freeaddrinfo (ai);
165 0 : return ret;
166 : }
167 0 : strlwr (*new_hostname);
168 0 : ret = krb5_get_host_realm (context, *new_hostname, realms);
169 0 : if (ret == 0) {
170 0 : freeaddrinfo (ai);
171 0 : return 0;
172 : }
173 0 : free (*new_hostname);
174 : }
175 : }
176 0 : freeaddrinfo(ai);
177 0 : return vanilla_hostname (context, orig_hostname, new_hostname, realms);
178 : }
|