]>
Commit | Line | Data |
---|---|---|
53e1b683 | 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ |
4e8c8252 | 2 | /*** |
cbc06dcd | 3 | This file is part of systemd. |
4e8c8252 | 4 | |
8041b5ba | 5 | Copyright 2008-2011 Lennart Poettering |
4e8c8252 | 6 | |
cbc06dcd TG |
7 | systemd is free software; you can redistribute it and/or modify it |
8 | under the terms of the GNU Lesser General Public License as published by | |
9 | the Free Software Foundation; either version 2.1 of the License, or | |
10 | (at your option) any later version. | |
4e8c8252 | 11 | |
cbc06dcd TG |
12 | systemd is distributed in the hope that it will be useful, but |
13 | WITHOUT ANY WARRANTY; without even the implied warranty of | |
8041b5ba LP |
14 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 | Lesser General Public License for more details. | |
4e8c8252 | 16 | |
cbc06dcd TG |
17 | You should have received a copy of the GNU Lesser General Public License |
18 | along with systemd; If not, see <http://www.gnu.org/licenses/>. | |
4e8c8252 | 19 | ***/ |
6b21f0cf | 20 | |
6b21f0cf | 21 | #include <errno.h> |
4e8c8252 | 22 | #include <net/if.h> |
07630cea LP |
23 | #include <netdb.h> |
24 | #include <nss.h> | |
8041b5ba | 25 | #include <stdlib.h> |
07630cea | 26 | #include <string.h> |
8041b5ba | 27 | |
b5efdb8a | 28 | #include "alloc-util.h" |
07630cea | 29 | #include "hostname-util.h" |
e80af1bd | 30 | #include "local-addresses.h" |
1c633045 | 31 | #include "macro.h" |
c9fdc26e | 32 | #include "nss-util.h" |
0c5eb056 | 33 | #include "signal-util.h" |
07630cea | 34 | #include "string-util.h" |
c9fdc26e | 35 | #include "util.h" |
4e8c8252 LP |
36 | |
37 | /* We use 127.0.0.2 as IPv4 address. This has the advantage over | |
38 | * 127.0.0.1 that it can be translated back to the local hostname. For | |
39 | * IPv6 we use ::1 which unfortunately will not translate back to the | |
3fdcecc8 | 40 | * hostname but instead something like "localhost" or so. */ |
4e8c8252 | 41 | |
8e38570e | 42 | #define LOCALADDRESS_IPV4 (htobe32(0x7F000002)) |
4e8c8252 | 43 | #define LOCALADDRESS_IPV6 &in6addr_loopback |
4e8c8252 | 44 | |
c9fdc26e LP |
45 | NSS_GETHOSTBYNAME_PROTOTYPES(myhostname); |
46 | NSS_GETHOSTBYADDR_PROTOTYPES(myhostname); | |
8041b5ba | 47 | |
4e8c8252 LP |
48 | enum nss_status _nss_myhostname_gethostbyname4_r( |
49 | const char *name, | |
50 | struct gaih_addrtuple **pat, | |
51 | char *buffer, size_t buflen, | |
52 | int *errnop, int *h_errnop, | |
53 | int32_t *ttlp) { | |
54 | ||
8041b5ba | 55 | struct gaih_addrtuple *r_tuple, *r_tuple_prev = NULL; |
e80af1bd | 56 | _cleanup_free_ struct local_address *addresses = NULL; |
5502f0d9 LP |
57 | _cleanup_free_ char *hn = NULL; |
58 | const char *canonical = NULL; | |
a1077c84 | 59 | int n_addresses = 0; |
e8a7a315 | 60 | uint32_t local_address_ipv4; |
e80af1bd | 61 | struct local_address *a; |
5502f0d9 LP |
62 | size_t l, idx, ms; |
63 | char *r_name; | |
e80af1bd | 64 | unsigned n; |
4e8c8252 | 65 | |
0c5eb056 LP |
66 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); |
67 | ||
5502f0d9 LP |
68 | assert(name); |
69 | assert(pat); | |
70 | assert(buffer); | |
71 | assert(errnop); | |
72 | assert(h_errnop); | |
73 | ||
74 | if (is_localhost(name)) { | |
e8a7a315 LP |
75 | /* We respond to 'localhost', so that /etc/hosts |
76 | * is optional */ | |
4e8c8252 | 77 | |
e8a7a315 | 78 | canonical = "localhost"; |
8e38570e | 79 | local_address_ipv4 = htobe32(INADDR_LOOPBACK); |
e9140aff | 80 | |
46a5e0e7 | 81 | } else if (is_gateway_hostname(name)) { |
e9140aff | 82 | |
1d050e1e | 83 | n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses); |
e9140aff LP |
84 | if (n_addresses <= 0) { |
85 | *errnop = ENOENT; | |
86 | *h_errnop = HOST_NOT_FOUND; | |
87 | return NSS_STATUS_NOTFOUND; | |
88 | } | |
89 | ||
5248e7e1 | 90 | canonical = "_gateway"; |
e9140aff | 91 | |
e8a7a315 | 92 | } else { |
5502f0d9 LP |
93 | hn = gethostname_malloc(); |
94 | if (!hn) { | |
95 | *errnop = ENOMEM; | |
e8a7a315 | 96 | *h_errnop = NO_RECOVERY; |
5502f0d9 | 97 | return NSS_STATUS_TRYAGAIN; |
e8a7a315 LP |
98 | } |
99 | ||
61233823 | 100 | /* We respond to our local host name, our hostname suffixed with a single dot. */ |
5502f0d9 | 101 | if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) { |
e8a7a315 LP |
102 | *errnop = ENOENT; |
103 | *h_errnop = HOST_NOT_FOUND; | |
104 | return NSS_STATUS_NOTFOUND; | |
105 | } | |
106 | ||
1d050e1e | 107 | n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses); |
e80af1bd LP |
108 | if (n_addresses < 0) |
109 | n_addresses = 0; | |
e8a7a315 LP |
110 | |
111 | canonical = hn; | |
112 | local_address_ipv4 = LOCALADDRESS_IPV4; | |
113 | } | |
8041b5ba | 114 | |
e8a7a315 | 115 | l = strlen(canonical); |
5502f0d9 | 116 | ms = ALIGN(l+1) + ALIGN(sizeof(struct gaih_addrtuple)) * (n_addresses > 0 ? n_addresses : 2); |
4e8c8252 | 117 | if (buflen < ms) { |
cda458a5 LP |
118 | *errnop = ERANGE; |
119 | *h_errnop = NETDB_INTERNAL; | |
4e8c8252 LP |
120 | return NSS_STATUS_TRYAGAIN; |
121 | } | |
122 | ||
123 | /* First, fill in hostname */ | |
124 | r_name = buffer; | |
e8a7a315 | 125 | memcpy(r_name, canonical, l+1); |
4e8c8252 LP |
126 | idx = ALIGN(l+1); |
127 | ||
68a9c7c4 ZJS |
128 | assert(n_addresses >= 0); |
129 | if (n_addresses == 0) { | |
8041b5ba LP |
130 | /* Second, fill in IPv6 tuple */ |
131 | r_tuple = (struct gaih_addrtuple*) (buffer + idx); | |
132 | r_tuple->next = r_tuple_prev; | |
133 | r_tuple->name = r_name; | |
134 | r_tuple->family = AF_INET6; | |
135 | memcpy(r_tuple->addr, LOCALADDRESS_IPV6, 16); | |
a1077c84 | 136 | r_tuple->scopeid = 0; |
8041b5ba LP |
137 | |
138 | idx += ALIGN(sizeof(struct gaih_addrtuple)); | |
139 | r_tuple_prev = r_tuple; | |
140 | ||
141 | /* Third, fill in IPv4 tuple */ | |
142 | r_tuple = (struct gaih_addrtuple*) (buffer + idx); | |
143 | r_tuple->next = r_tuple_prev; | |
144 | r_tuple->name = r_name; | |
145 | r_tuple->family = AF_INET; | |
e8a7a315 | 146 | *(uint32_t*) r_tuple->addr = local_address_ipv4; |
a1077c84 | 147 | r_tuple->scopeid = 0; |
8041b5ba LP |
148 | |
149 | idx += ALIGN(sizeof(struct gaih_addrtuple)); | |
150 | r_tuple_prev = r_tuple; | |
151 | } | |
152 | ||
153 | /* Fourth, fill actual addresses in, but in backwards order */ | |
e80af1bd | 154 | for (a = addresses + n_addresses - 1, n = 0; (int) n < n_addresses; n++, a--) { |
8041b5ba LP |
155 | r_tuple = (struct gaih_addrtuple*) (buffer + idx); |
156 | r_tuple->next = r_tuple_prev; | |
157 | r_tuple->name = r_name; | |
158 | r_tuple->family = a->family; | |
a1077c84 | 159 | r_tuple->scopeid = a->family == AF_INET6 && IN6_IS_ADDR_LINKLOCAL(&a->address.in6) ? a->ifindex : 0; |
5502f0d9 | 160 | memcpy(r_tuple->addr, &a->address, 16); |
8041b5ba LP |
161 | |
162 | idx += ALIGN(sizeof(struct gaih_addrtuple)); | |
163 | r_tuple_prev = r_tuple; | |
164 | } | |
4e8c8252 LP |
165 | |
166 | /* Verify the size matches */ | |
167 | assert(idx == ms); | |
168 | ||
d2f1f23a ED |
169 | /* Nscd expects us to store the first record in **pat. */ |
170 | if (*pat) | |
171 | **pat = *r_tuple_prev; | |
172 | else | |
173 | *pat = r_tuple_prev; | |
4e8c8252 LP |
174 | |
175 | if (ttlp) | |
176 | *ttlp = 0; | |
177 | ||
e70df46b LP |
178 | /* Explicitly reset all error variables */ |
179 | *errnop = 0; | |
180 | *h_errnop = NETDB_SUCCESS; | |
181 | h_errno = 0; | |
182 | ||
4e8c8252 LP |
183 | return NSS_STATUS_SUCCESS; |
184 | } | |
6b21f0cf LP |
185 | |
186 | static enum nss_status fill_in_hostent( | |
e8a7a315 | 187 | const char *canonical, const char *additional, |
4e8c8252 | 188 | int af, |
e80af1bd | 189 | struct local_address *addresses, unsigned n_addresses, |
e8a7a315 | 190 | uint32_t local_address_ipv4, |
4e8c8252 LP |
191 | struct hostent *result, |
192 | char *buffer, size_t buflen, | |
193 | int *errnop, int *h_errnop, | |
194 | int32_t *ttlp, | |
195 | char **canonp) { | |
196 | ||
d4c9895d | 197 | size_t l_canonical, l_additional, idx, ms, alen; |
e8a7a315 | 198 | char *r_addr, *r_name, *r_aliases, *r_alias = NULL, *r_addr_list; |
e80af1bd | 199 | struct local_address *a; |
e8a7a315 | 200 | unsigned n, c; |
8041b5ba | 201 | |
5502f0d9 LP |
202 | assert(canonical); |
203 | assert(result); | |
204 | assert(buffer); | |
205 | assert(errnop); | |
206 | assert(h_errnop); | |
207 | ||
9d485985 | 208 | alen = FAMILY_ADDRESS_SIZE(af); |
8041b5ba | 209 | |
8041b5ba LP |
210 | for (a = addresses, n = 0, c = 0; n < n_addresses; a++, n++) |
211 | if (af == a->family) | |
212 | c++; | |
4e8c8252 | 213 | |
e8a7a315 | 214 | l_canonical = strlen(canonical); |
7bf7ce28 | 215 | l_additional = strlen_ptr(additional); |
e8a7a315 LP |
216 | ms = ALIGN(l_canonical+1)+ |
217 | (additional ? ALIGN(l_additional+1) : 0) + | |
5502f0d9 | 218 | sizeof(char*) + |
e8a7a315 | 219 | (additional ? sizeof(char*) : 0) + |
d4c9895d | 220 | (c > 0 ? c : 1) * ALIGN(alen) + |
5502f0d9 | 221 | (c > 0 ? c+1 : 2) * sizeof(char*); |
8041b5ba | 222 | |
4e8c8252 | 223 | if (buflen < ms) { |
cda458a5 LP |
224 | *errnop = ERANGE; |
225 | *h_errnop = NETDB_INTERNAL; | |
4e8c8252 LP |
226 | return NSS_STATUS_TRYAGAIN; |
227 | } | |
228 | ||
e8a7a315 | 229 | /* First, fill in hostnames */ |
4e8c8252 | 230 | r_name = buffer; |
e8a7a315 LP |
231 | memcpy(r_name, canonical, l_canonical+1); |
232 | idx = ALIGN(l_canonical+1); | |
4e8c8252 | 233 | |
e8a7a315 LP |
234 | if (additional) { |
235 | r_alias = buffer + idx; | |
236 | memcpy(r_alias, additional, l_additional+1); | |
237 | idx += ALIGN(l_additional+1); | |
238 | } | |
239 | ||
240 | /* Second, create aliases array */ | |
4e8c8252 | 241 | r_aliases = buffer + idx; |
e8a7a315 LP |
242 | if (additional) { |
243 | ((char**) r_aliases)[0] = r_alias; | |
244 | ((char**) r_aliases)[1] = NULL; | |
245 | idx += 2*sizeof(char*); | |
246 | } else { | |
247 | ((char**) r_aliases)[0] = NULL; | |
248 | idx += sizeof(char*); | |
249 | } | |
4e8c8252 | 250 | |
8041b5ba | 251 | /* Third, add addresses */ |
4e8c8252 | 252 | r_addr = buffer + idx; |
8041b5ba LP |
253 | if (c > 0) { |
254 | unsigned i = 0; | |
255 | ||
256 | for (a = addresses, n = 0; n < n_addresses; a++, n++) { | |
257 | if (af != a->family) | |
258 | continue; | |
259 | ||
5502f0d9 | 260 | memcpy(r_addr + i*ALIGN(alen), &a->address, alen); |
8041b5ba LP |
261 | i++; |
262 | } | |
263 | ||
264 | assert(i == c); | |
265 | idx += c*ALIGN(alen); | |
266 | } else { | |
267 | if (af == AF_INET) | |
e8a7a315 | 268 | *(uint32_t*) r_addr = local_address_ipv4; |
8041b5ba LP |
269 | else |
270 | memcpy(r_addr, LOCALADDRESS_IPV6, 16); | |
271 | ||
272 | idx += ALIGN(alen); | |
273 | } | |
4e8c8252 LP |
274 | |
275 | /* Fourth, add address pointer array */ | |
276 | r_addr_list = buffer + idx; | |
8041b5ba | 277 | if (c > 0) { |
d4c9895d | 278 | unsigned i; |
8041b5ba | 279 | |
d4c9895d LP |
280 | for (i = 0; i < c; i++) |
281 | ((char**) r_addr_list)[i] = r_addr + i*ALIGN(alen); | |
8041b5ba | 282 | |
d4c9895d LP |
283 | ((char**) r_addr_list)[i] = NULL; |
284 | idx += (c+1) * sizeof(char*); | |
8041b5ba LP |
285 | |
286 | } else { | |
287 | ((char**) r_addr_list)[0] = r_addr; | |
288 | ((char**) r_addr_list)[1] = NULL; | |
d4c9895d | 289 | idx += 2 * sizeof(char*); |
8041b5ba | 290 | } |
4e8c8252 LP |
291 | |
292 | /* Verify the size matches */ | |
293 | assert(idx == ms); | |
294 | ||
295 | result->h_name = r_name; | |
296 | result->h_aliases = (char**) r_aliases; | |
297 | result->h_addrtype = af; | |
298 | result->h_length = alen; | |
299 | result->h_addr_list = (char**) r_addr_list; | |
300 | ||
301 | if (ttlp) | |
302 | *ttlp = 0; | |
303 | ||
304 | if (canonp) | |
305 | *canonp = r_name; | |
306 | ||
e70df46b LP |
307 | /* Explicitly reset all error variables */ |
308 | *errnop = 0; | |
309 | *h_errnop = NETDB_SUCCESS; | |
310 | h_errno = 0; | |
311 | ||
4e8c8252 | 312 | return NSS_STATUS_SUCCESS; |
6b21f0cf LP |
313 | } |
314 | ||
4e8c8252 LP |
315 | enum nss_status _nss_myhostname_gethostbyname3_r( |
316 | const char *name, | |
317 | int af, | |
318 | struct hostent *host, | |
319 | char *buffer, size_t buflen, | |
320 | int *errnop, int *h_errnop, | |
321 | int32_t *ttlp, | |
322 | char **canonp) { | |
6b21f0cf | 323 | |
e80af1bd | 324 | _cleanup_free_ struct local_address *addresses = NULL; |
e8a7a315 | 325 | const char *canonical, *additional = NULL; |
5502f0d9 | 326 | _cleanup_free_ char *hn = NULL; |
e9140aff | 327 | uint32_t local_address_ipv4 = 0; |
e80af1bd | 328 | int n_addresses = 0; |
5502f0d9 | 329 | |
0c5eb056 LP |
330 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); |
331 | ||
5502f0d9 LP |
332 | assert(name); |
333 | assert(host); | |
334 | assert(buffer); | |
335 | assert(errnop); | |
336 | assert(h_errnop); | |
6b21f0cf | 337 | |
4e8c8252 LP |
338 | if (af == AF_UNSPEC) |
339 | af = AF_INET; | |
6b21f0cf | 340 | |
ec2ce0c5 | 341 | if (!IN_SET(af, AF_INET, AF_INET6)) { |
4e8c8252 LP |
342 | *errnop = EAFNOSUPPORT; |
343 | *h_errnop = NO_DATA; | |
344 | return NSS_STATUS_UNAVAIL; | |
345 | } | |
6b21f0cf | 346 | |
5502f0d9 | 347 | if (is_localhost(name)) { |
e8a7a315 | 348 | canonical = "localhost"; |
8e38570e | 349 | local_address_ipv4 = htobe32(INADDR_LOOPBACK); |
e9140aff | 350 | |
46a5e0e7 | 351 | } else if (is_gateway_hostname(name)) { |
e9140aff | 352 | |
1d050e1e | 353 | n_addresses = local_gateways(NULL, 0, af, &addresses); |
e9140aff LP |
354 | if (n_addresses <= 0) { |
355 | *errnop = ENOENT; | |
356 | *h_errnop = HOST_NOT_FOUND; | |
357 | return NSS_STATUS_NOTFOUND; | |
358 | } | |
359 | ||
5248e7e1 | 360 | canonical = "_gateway"; |
e9140aff | 361 | |
e8a7a315 | 362 | } else { |
5502f0d9 LP |
363 | hn = gethostname_malloc(); |
364 | if (!hn) { | |
365 | *errnop = ENOMEM; | |
e8a7a315 | 366 | *h_errnop = NO_RECOVERY; |
5502f0d9 | 367 | return NSS_STATUS_TRYAGAIN; |
e8a7a315 | 368 | } |
6b21f0cf | 369 | |
5502f0d9 | 370 | if (!streq(name, hn) && !streq_ptr(startswith(name, hn), ".")) { |
e8a7a315 LP |
371 | *errnop = ENOENT; |
372 | *h_errnop = HOST_NOT_FOUND; | |
373 | return NSS_STATUS_NOTFOUND; | |
374 | } | |
375 | ||
1d050e1e | 376 | n_addresses = local_addresses(NULL, 0, af, &addresses); |
e80af1bd LP |
377 | if (n_addresses < 0) |
378 | n_addresses = 0; | |
e8a7a315 LP |
379 | |
380 | canonical = hn; | |
381 | additional = n_addresses <= 0 && af == AF_INET6 ? "localhost" : NULL; | |
382 | local_address_ipv4 = LOCALADDRESS_IPV4; | |
4e8c8252 | 383 | } |
6b21f0cf | 384 | |
e8a7a315 LP |
385 | return fill_in_hostent( |
386 | canonical, additional, | |
387 | af, | |
388 | addresses, n_addresses, | |
389 | local_address_ipv4, | |
390 | host, | |
391 | buffer, buflen, | |
392 | errnop, h_errnop, | |
393 | ttlp, | |
394 | canonp); | |
4e8c8252 | 395 | } |
6b21f0cf | 396 | |
4e8c8252 LP |
397 | enum nss_status _nss_myhostname_gethostbyaddr2_r( |
398 | const void* addr, socklen_t len, | |
399 | int af, | |
400 | struct hostent *host, | |
401 | char *buffer, size_t buflen, | |
402 | int *errnop, int *h_errnop, | |
403 | int32_t *ttlp) { | |
6b21f0cf | 404 | |
e8a7a315 | 405 | const char *canonical = NULL, *additional = NULL; |
5502f0d9 | 406 | uint32_t local_address_ipv4 = LOCALADDRESS_IPV4; |
e80af1bd | 407 | _cleanup_free_ struct local_address *addresses = NULL; |
5502f0d9 | 408 | _cleanup_free_ char *hn = NULL; |
e80af1bd LP |
409 | int n_addresses = 0; |
410 | struct local_address *a; | |
3fdcecc8 | 411 | bool additional_from_hostname = false; |
e80af1bd | 412 | unsigned n; |
5502f0d9 | 413 | |
0c5eb056 LP |
414 | BLOCK_SIGNALS(NSS_SIGNALS_BLOCK); |
415 | ||
5502f0d9 LP |
416 | assert(addr); |
417 | assert(host); | |
418 | assert(buffer); | |
419 | assert(errnop); | |
420 | assert(h_errnop); | |
8041b5ba | 421 | |
555bd6e9 LP |
422 | if (!IN_SET(af, AF_INET, AF_INET6)) { |
423 | *errnop = EAFNOSUPPORT; | |
424 | *h_errnop = NO_DATA; | |
425 | return NSS_STATUS_UNAVAIL; | |
426 | } | |
427 | ||
9d485985 | 428 | if (len != FAMILY_ADDRESS_SIZE(af)) { |
8041b5ba LP |
429 | *errnop = EINVAL; |
430 | *h_errnop = NO_RECOVERY; | |
431 | return NSS_STATUS_UNAVAIL; | |
432 | } | |
6b21f0cf | 433 | |
4e8c8252 | 434 | if (af == AF_INET) { |
8041b5ba LP |
435 | if ((*(uint32_t*) addr) == LOCALADDRESS_IPV4) |
436 | goto found; | |
6b21f0cf | 437 | |
8e38570e | 438 | if ((*(uint32_t*) addr) == htobe32(INADDR_LOOPBACK)) { |
e8a7a315 | 439 | canonical = "localhost"; |
8e38570e | 440 | local_address_ipv4 = htobe32(INADDR_LOOPBACK); |
e8a7a315 LP |
441 | goto found; |
442 | } | |
443 | ||
555bd6e9 LP |
444 | } else { |
445 | assert(af == AF_INET6); | |
8041b5ba | 446 | |
e8a7a315 | 447 | if (memcmp(addr, LOCALADDRESS_IPV6, 16) == 0) { |
3fdcecc8 LP |
448 | canonical = "localhost"; |
449 | additional_from_hostname = true; | |
8041b5ba | 450 | goto found; |
e8a7a315 | 451 | } |
4e8c8252 LP |
452 | } |
453 | ||
1d050e1e | 454 | n_addresses = local_addresses(NULL, 0, AF_UNSPEC, &addresses); |
68a9c7c4 ZJS |
455 | for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) { |
456 | if (af != a->family) | |
457 | continue; | |
8041b5ba | 458 | |
68a9c7c4 ZJS |
459 | if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) |
460 | goto found; | |
e9140aff LP |
461 | } |
462 | ||
97b11eed | 463 | addresses = mfree(addresses); |
e9140aff | 464 | |
1d050e1e | 465 | n_addresses = local_gateways(NULL, 0, AF_UNSPEC, &addresses); |
68a9c7c4 ZJS |
466 | for (a = addresses, n = 0; (int) n < n_addresses; n++, a++) { |
467 | if (af != a->family) | |
468 | continue; | |
e9140aff | 469 | |
68a9c7c4 | 470 | if (memcmp(addr, &a->address, FAMILY_ADDRESS_SIZE(af)) == 0) { |
5248e7e1 | 471 | canonical = "_gateway"; |
68a9c7c4 | 472 | goto found; |
e9140aff | 473 | } |
8041b5ba LP |
474 | } |
475 | ||
476 | *errnop = ENOENT; | |
477 | *h_errnop = HOST_NOT_FOUND; | |
8041b5ba LP |
478 | return NSS_STATUS_NOTFOUND; |
479 | ||
480 | found: | |
82e4c2d6 | 481 | if (!canonical || additional_from_hostname) { |
3fdcecc8 LP |
482 | hn = gethostname_malloc(); |
483 | if (!hn) { | |
484 | *errnop = ENOMEM; | |
485 | *h_errnop = NO_RECOVERY; | |
486 | return NSS_STATUS_TRYAGAIN; | |
487 | } | |
488 | ||
489 | if (!canonical) | |
490 | canonical = hn; | |
82e4c2d6 | 491 | else |
3fdcecc8 LP |
492 | additional = hn; |
493 | } | |
4e8c8252 | 494 | |
e8a7a315 LP |
495 | return fill_in_hostent( |
496 | canonical, additional, | |
497 | af, | |
498 | addresses, n_addresses, | |
499 | local_address_ipv4, | |
500 | host, | |
501 | buffer, buflen, | |
502 | errnop, h_errnop, | |
503 | ttlp, | |
504 | NULL); | |
4e8c8252 | 505 | } |
6b21f0cf | 506 | |
c9fdc26e LP |
507 | NSS_GETHOSTBYNAME_FALLBACKS(myhostname); |
508 | NSS_GETHOSTBYADDR_FALLBACKS(myhostname); |