]>
Commit | Line | Data |
---|---|---|
04277e02 | 1 | /* Copyright (C) 1996-2019 Free Software Foundation, Inc. |
6259ec0d | 2 | This file is part of the GNU C Library. |
1e275b9e | 3 | Contributed by Thorsten Kukuk <kukuk@suse.de>, 1996. |
6259ec0d UD |
4 | |
5 | The GNU C Library is free software; you can redistribute it and/or | |
41bdb6e2 AJ |
6 | modify it under the terms of the GNU Lesser General Public |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
6259ec0d UD |
9 | |
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
41bdb6e2 | 13 | Lesser General Public License for more details. |
6259ec0d | 14 | |
41bdb6e2 | 15 | You should have received a copy of the GNU Lesser General Public |
59ba27a6 PE |
16 | License along with the GNU C Library; if not, see |
17 | <http://www.gnu.org/licenses/>. */ | |
6259ec0d | 18 | |
1eb946b9 | 19 | #include <assert.h> |
6259ec0d UD |
20 | #include <nss.h> |
21 | #include <ctype.h> | |
6675b191 UD |
22 | /* The following is an ugly trick to avoid a prototype declaration for |
23 | _nss_nis_endgrent. */ | |
24 | #define _nss_nis_endhostent _nss_nis_endhostent_XXX | |
6259ec0d | 25 | #include <netdb.h> |
6675b191 | 26 | #undef _nss_nis_endhostent |
6259ec0d UD |
27 | #include <string.h> |
28 | #include <netinet/in.h> | |
29 | #include <arpa/inet.h> | |
ec999b8e | 30 | #include <libc-lock.h> |
6259ec0d UD |
31 | #include <rpcsvc/yp.h> |
32 | #include <rpcsvc/ypclnt.h> | |
33 | ||
34 | #include "nss-nis.h" | |
35 | ||
6259ec0d UD |
36 | #define ENTNAME hostent |
37 | #define DATABASE "hosts" | |
38 | #define NEED_H_ERRNO | |
39 | ||
ec255a97 FW |
40 | #define EXTRA_ARGS , af |
41 | #define EXTRA_ARGS_DECL , int af | |
1e275b9e | 42 | |
6259ec0d UD |
43 | #define ENTDATA hostent_data |
44 | struct hostent_data | |
45 | { | |
46 | unsigned char host_addr[16]; /* IPv4 or IPv6 address. */ | |
47 | char *h_addr_ptrs[2]; /* Points to that and null terminator. */ | |
48 | }; | |
49 | ||
50 | #define TRAILING_LIST_MEMBER h_aliases | |
51 | #define TRAILING_LIST_SEPARATOR_P isspace | |
cf29ffbe | 52 | #include <nss/nss_files/files-parse.c> |
6259ec0d UD |
53 | LINE_PARSER |
54 | ("#", | |
55 | { | |
56 | char *addr; | |
57 | ||
58 | STRING_FIELD (addr, isspace, 1); | |
59 | ||
1eb946b9 UD |
60 | assert (af == AF_INET || af == AF_INET6 || af == AF_UNSPEC); |
61 | ||
6259ec0d | 62 | /* Parse address. */ |
1eb946b9 | 63 | if (af != AF_INET6 && inet_pton (AF_INET, addr, entdata->host_addr) > 0) |
1e275b9e | 64 | { |
ec255a97 FW |
65 | result->h_addrtype = AF_INET; |
66 | result->h_length = INADDRSZ; | |
1e275b9e | 67 | } |
1eb946b9 | 68 | else if (af != AF_INET |
a682a1bf | 69 | && inet_pton (AF_INET6, addr, entdata->host_addr) > 0) |
6259ec0d UD |
70 | { |
71 | result->h_addrtype = AF_INET6; | |
72 | result->h_length = IN6ADDRSZ; | |
73 | } | |
74 | else | |
1e275b9e UD |
75 | /* Illegal address: ignore line. */ |
76 | return 0; | |
6259ec0d UD |
77 | |
78 | /* Store a pointer to the address in the expected form. */ | |
701666b7 | 79 | entdata->h_addr_ptrs[0] = (char *) entdata->host_addr; |
6259ec0d UD |
80 | entdata->h_addr_ptrs[1] = NULL; |
81 | result->h_addr_list = entdata->h_addr_ptrs; | |
82 | ||
6259ec0d | 83 | STRING_FIELD (result->h_name, isspace, 1); |
1e275b9e UD |
84 | }) |
85 | ||
6259ec0d UD |
86 | |
87 | __libc_lock_define_initialized (static, lock) | |
88 | ||
89 | static bool_t new_start = 1; | |
90 | static char *oldkey = NULL; | |
91 | static int oldkeylen = 0; | |
92 | ||
1eb946b9 | 93 | |
6259ec0d | 94 | enum nss_status |
51eecc4a | 95 | _nss_nis_sethostent (int stayopen) |
6259ec0d UD |
96 | { |
97 | __libc_lock_lock (lock); | |
98 | ||
99 | new_start = 1; | |
100 | if (oldkey != NULL) | |
101 | { | |
102 | free (oldkey); | |
103 | oldkey = NULL; | |
104 | oldkeylen = 0; | |
105 | } | |
106 | ||
107 | __libc_lock_unlock (lock); | |
108 | ||
109 | return NSS_STATUS_SUCCESS; | |
110 | } | |
6675b191 UD |
111 | /* Make _nss_nis_endhostent an alias of _nss_nis_sethostent. We do this |
112 | even though the prototypes don't match. The argument of sethostent | |
113 | is used so this makes no difference. */ | |
114 | strong_alias (_nss_nis_sethostent, _nss_nis_endhostent) | |
6259ec0d | 115 | |
1eb946b9 | 116 | |
1e275b9e | 117 | /* The calling function always need to get a lock first. */ |
6259ec0d UD |
118 | static enum nss_status |
119 | internal_nis_gethostent_r (struct hostent *host, char *buffer, | |
1e275b9e | 120 | size_t buflen, int *errnop, int *h_errnop, |
ec255a97 | 121 | int af) |
6259ec0d UD |
122 | { |
123 | char *domain; | |
a1ffb40e | 124 | if (__glibc_unlikely (yp_get_default_domain (&domain))) |
a334319f | 125 | return NSS_STATUS_UNAVAIL; |
0ecb606c | 126 | |
2f1687b9 UD |
127 | uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); |
128 | buffer += pad; | |
129 | ||
ab9a9ff8 | 130 | struct parser_data *data = (void *) buffer; |
a1ffb40e | 131 | if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) |
6259ec0d | 132 | { |
d71b808a | 133 | *errnop = ERANGE; |
6259ec0d UD |
134 | *h_errnop = NETDB_INTERNAL; |
135 | return NSS_STATUS_TRYAGAIN; | |
136 | } | |
2f1687b9 | 137 | buflen -= pad; |
6259ec0d UD |
138 | |
139 | /* Get the next entry until we found a correct one. */ | |
ab9a9ff8 UD |
140 | const size_t linebuflen = buffer + buflen - data->linebuffer; |
141 | int parse_res; | |
6259ec0d UD |
142 | do |
143 | { | |
ab9a9ff8 UD |
144 | char *result; |
145 | int len; | |
146 | char *outkey; | |
147 | int keylen; | |
148 | int yperr; | |
6259ec0d | 149 | if (new_start) |
a682a1bf | 150 | yperr = yp_first (domain, "hosts.byname", &outkey, &keylen, &result, |
ab9a9ff8 | 151 | &len); |
6259ec0d | 152 | else |
a682a1bf | 153 | yperr = yp_next (domain, "hosts.byname", oldkey, oldkeylen, &outkey, |
ab9a9ff8 | 154 | &keylen, &result, &len); |
6259ec0d | 155 | |
a1ffb40e | 156 | if (__glibc_unlikely (yperr != YPERR_SUCCESS)) |
a682a1bf | 157 | { |
ab9a9ff8 UD |
158 | enum nss_status retval = yperr2nss (yperr); |
159 | ||
6259ec0d UD |
160 | switch (retval) |
161 | { | |
162 | case NSS_STATUS_TRYAGAIN: | |
d71b808a | 163 | *errnop = errno; |
6259ec0d UD |
164 | *h_errnop = TRY_AGAIN; |
165 | break; | |
166 | case NSS_STATUS_NOTFOUND: | |
167 | *h_errnop = HOST_NOT_FOUND; | |
168 | break; | |
169 | default: | |
170 | *h_errnop = NO_RECOVERY; | |
171 | break; | |
172 | } | |
173 | return retval; | |
174 | } | |
175 | ||
a1ffb40e | 176 | if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) |
a682a1bf UD |
177 | { |
178 | free (result); | |
6259ec0d | 179 | *h_errnop = NETDB_INTERNAL; |
a682a1bf UD |
180 | *errnop = ERANGE; |
181 | return NSS_STATUS_TRYAGAIN; | |
182 | } | |
6259ec0d | 183 | |
ab9a9ff8 | 184 | char *p = strncpy (data->linebuffer, result, len); |
6259ec0d UD |
185 | data->linebuffer[len] = '\0'; |
186 | while (isspace (*p)) | |
187 | ++p; | |
188 | free (result); | |
189 | ||
ec255a97 | 190 | parse_res = parse_line (p, host, data, buflen, errnop, af); |
a1ffb40e | 191 | if (__glibc_unlikely (parse_res == -1)) |
6259ec0d | 192 | { |
60c96635 | 193 | free (outkey); |
d71b808a UD |
194 | *h_errnop = NETDB_INTERNAL; |
195 | *errnop = ERANGE; | |
6259ec0d UD |
196 | return NSS_STATUS_TRYAGAIN; |
197 | } | |
198 | free (oldkey); | |
199 | oldkey = outkey; | |
200 | oldkeylen = keylen; | |
201 | new_start = 0; | |
202 | } | |
203 | while (!parse_res); | |
204 | ||
205 | *h_errnop = NETDB_SUCCESS; | |
206 | return NSS_STATUS_SUCCESS; | |
207 | } | |
208 | ||
1eb946b9 | 209 | |
1e275b9e | 210 | enum nss_status |
6259ec0d | 211 | _nss_nis_gethostent_r (struct hostent *host, char *buffer, size_t buflen, |
d71b808a | 212 | int *errnop, int *h_errnop) |
6259ec0d | 213 | { |
1e275b9e | 214 | enum nss_status status; |
6259ec0d UD |
215 | |
216 | __libc_lock_lock (lock); | |
217 | ||
1e275b9e | 218 | status = internal_nis_gethostent_r (host, buffer, buflen, errnop, h_errnop, |
ec255a97 | 219 | AF_INET); |
6259ec0d UD |
220 | |
221 | __libc_lock_unlock (lock); | |
222 | ||
223 | return status; | |
224 | } | |
225 | ||
1eb946b9 | 226 | |
1e275b9e UD |
227 | static enum nss_status |
228 | internal_gethostbyname2_r (const char *name, int af, struct hostent *host, | |
d71b808a | 229 | char *buffer, size_t buflen, int *errnop, |
ec255a97 | 230 | int *h_errnop) |
6259ec0d | 231 | { |
2f1687b9 UD |
232 | uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); |
233 | buffer += pad; | |
234 | ||
6259ec0d | 235 | struct parser_data *data = (void *) buffer; |
6259ec0d UD |
236 | |
237 | if (name == NULL) | |
238 | { | |
ac9f45cf | 239 | *errnop = EINVAL; |
6259ec0d UD |
240 | return NSS_STATUS_UNAVAIL; |
241 | } | |
242 | ||
ab9a9ff8 | 243 | char *domain; |
6259ec0d UD |
244 | if (yp_get_default_domain (&domain)) |
245 | return NSS_STATUS_UNAVAIL; | |
246 | ||
2f1687b9 | 247 | if (buflen < sizeof *data + 1 + pad) |
6259ec0d UD |
248 | { |
249 | *h_errnop = NETDB_INTERNAL; | |
d71b808a | 250 | *errnop = ERANGE; |
6259ec0d UD |
251 | return NSS_STATUS_TRYAGAIN; |
252 | } | |
2f1687b9 | 253 | buflen -= pad; |
cd897fe7 | 254 | |
ab9a9ff8 UD |
255 | /* Convert name to lowercase. */ |
256 | size_t namlen = strlen (name); | |
315eb1d8 AS |
257 | /* Limit name length to the maximum size of an RPC packet. */ |
258 | if (namlen > UDPMSGSIZE) | |
259 | { | |
260 | *errnop = ERANGE; | |
261 | return NSS_STATUS_UNAVAIL; | |
262 | } | |
263 | ||
ab9a9ff8 UD |
264 | char name2[namlen + 1]; |
265 | size_t i; | |
cd897fe7 | 266 | |
ab9a9ff8 UD |
267 | for (i = 0; i < namlen; ++i) |
268 | name2[i] = tolower (name[i]); | |
269 | name2[i] = '\0'; | |
cd897fe7 | 270 | |
ab9a9ff8 UD |
271 | char *result; |
272 | int len; | |
273 | int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len); | |
6259ec0d | 274 | |
a1ffb40e | 275 | if (__glibc_unlikely (yperr != YPERR_SUCCESS)) |
6259ec0d | 276 | { |
ab9a9ff8 UD |
277 | enum nss_status retval = yperr2nss (yperr); |
278 | ||
6259ec0d UD |
279 | if (retval == NSS_STATUS_TRYAGAIN) |
280 | { | |
281 | *h_errnop = TRY_AGAIN; | |
d71b808a | 282 | *errnop = errno; |
6259ec0d UD |
283 | } |
284 | if (retval == NSS_STATUS_NOTFOUND) | |
285 | *h_errnop = HOST_NOT_FOUND; | |
286 | return retval; | |
287 | } | |
288 | ||
ab9a9ff8 | 289 | const size_t linebuflen = buffer + buflen - data->linebuffer; |
a1ffb40e | 290 | if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) |
6259ec0d UD |
291 | { |
292 | free (result); | |
293 | *h_errnop = NETDB_INTERNAL; | |
d71b808a | 294 | *errnop = ERANGE; |
6259ec0d UD |
295 | return NSS_STATUS_TRYAGAIN; |
296 | } | |
297 | ||
ab9a9ff8 | 298 | char *p = strncpy (data->linebuffer, result, len); |
6259ec0d UD |
299 | data->linebuffer[len] = '\0'; |
300 | while (isspace (*p)) | |
301 | ++p; | |
302 | free (result); | |
303 | ||
ec255a97 | 304 | int parse_res = parse_line (p, host, data, buflen, errnop, af); |
6259ec0d | 305 | |
a1ffb40e | 306 | if (__glibc_unlikely (parse_res < 1 || host->h_addrtype != af)) |
6259ec0d | 307 | { |
60c96635 | 308 | if (parse_res == -1) |
6259ec0d UD |
309 | { |
310 | *h_errnop = NETDB_INTERNAL; | |
311 | return NSS_STATUS_TRYAGAIN; | |
312 | } | |
313 | else | |
314 | { | |
315 | *h_errnop = HOST_NOT_FOUND; | |
316 | return NSS_STATUS_NOTFOUND; | |
317 | } | |
318 | } | |
319 | ||
320 | *h_errnop = NETDB_SUCCESS; | |
321 | return NSS_STATUS_SUCCESS; | |
322 | } | |
323 | ||
1eb946b9 | 324 | |
1e275b9e UD |
325 | enum nss_status |
326 | _nss_nis_gethostbyname2_r (const char *name, int af, struct hostent *host, | |
327 | char *buffer, size_t buflen, int *errnop, | |
328 | int *h_errnop) | |
329 | { | |
1eb946b9 UD |
330 | if (af != AF_INET && af != AF_INET6) |
331 | { | |
332 | *h_errnop = HOST_NOT_FOUND; | |
333 | return NSS_STATUS_NOTFOUND; | |
334 | } | |
335 | ||
1e275b9e | 336 | return internal_gethostbyname2_r (name, af, host, buffer, buflen, errnop, |
ec255a97 | 337 | h_errnop); |
1e275b9e UD |
338 | } |
339 | ||
1eb946b9 | 340 | |
0d8733c4 | 341 | enum nss_status |
d71b808a UD |
342 | _nss_nis_gethostbyname_r (const char *name, struct hostent *host, char *buffer, |
343 | size_t buflen, int *errnop, int *h_errnop) | |
0d8733c4 | 344 | { |
1e275b9e | 345 | return internal_gethostbyname2_r (name, AF_INET, host, buffer, buflen, |
ec255a97 | 346 | errnop, h_errnop); |
0d8733c4 UD |
347 | } |
348 | ||
1eb946b9 | 349 | |
6259ec0d | 350 | enum nss_status |
9d4d69b8 | 351 | _nss_nis_gethostbyaddr_r (const void *addr, socklen_t addrlen, int af, |
6259ec0d | 352 | struct hostent *host, char *buffer, size_t buflen, |
d71b808a | 353 | int *errnop, int *h_errnop) |
6259ec0d | 354 | { |
ab9a9ff8 | 355 | char *domain; |
a1ffb40e | 356 | if (__glibc_unlikely (yp_get_default_domain (&domain))) |
a334319f | 357 | return NSS_STATUS_UNAVAIL; |
0ecb606c | 358 | |
2f1687b9 UD |
359 | uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); |
360 | buffer += pad; | |
361 | ||
ab9a9ff8 | 362 | struct parser_data *data = (void *) buffer; |
a1ffb40e | 363 | if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) |
6259ec0d | 364 | { |
d71b808a | 365 | *errnop = ERANGE; |
6259ec0d UD |
366 | *h_errnop = NETDB_INTERNAL; |
367 | return NSS_STATUS_TRYAGAIN; | |
368 | } | |
2f1687b9 | 369 | buflen -= pad; |
6259ec0d | 370 | |
ab9a9ff8 | 371 | char *buf = inet_ntoa (*(const struct in_addr *) addr); |
6259ec0d | 372 | |
ab9a9ff8 UD |
373 | char *result; |
374 | int len; | |
375 | int yperr = yp_match (domain, "hosts.byaddr", buf, strlen (buf), &result, | |
376 | &len); | |
6259ec0d | 377 | |
a1ffb40e | 378 | if (__glibc_unlikely (yperr != YPERR_SUCCESS)) |
6259ec0d | 379 | { |
ab9a9ff8 UD |
380 | enum nss_status retval = yperr2nss (yperr); |
381 | ||
6259ec0d UD |
382 | if (retval == NSS_STATUS_TRYAGAIN) |
383 | { | |
384 | *h_errnop = TRY_AGAIN; | |
d71b808a | 385 | *errnop = errno; |
6259ec0d | 386 | } |
ab9a9ff8 | 387 | else if (retval == NSS_STATUS_NOTFOUND) |
34816665 UD |
388 | *h_errnop = HOST_NOT_FOUND; |
389 | ||
6259ec0d UD |
390 | return retval; |
391 | } | |
392 | ||
ab9a9ff8 | 393 | const size_t linebuflen = buffer + buflen - data->linebuffer; |
a1ffb40e | 394 | if (__glibc_unlikely ((size_t) (len + 1) > linebuflen)) |
6259ec0d UD |
395 | { |
396 | free (result); | |
d71b808a | 397 | *errnop = ERANGE; |
6259ec0d UD |
398 | *h_errnop = NETDB_INTERNAL; |
399 | return NSS_STATUS_TRYAGAIN; | |
400 | } | |
401 | ||
ab9a9ff8 | 402 | char *p = strncpy (data->linebuffer, result, len); |
6259ec0d UD |
403 | data->linebuffer[len] = '\0'; |
404 | while (isspace (*p)) | |
405 | ++p; | |
406 | free (result); | |
407 | ||
ec255a97 | 408 | int parse_res = parse_line (p, host, data, buflen, errnop, af); |
a1ffb40e | 409 | if (__glibc_unlikely (parse_res < 1)) |
6259ec0d | 410 | { |
60c96635 | 411 | if (parse_res == -1) |
6259ec0d UD |
412 | { |
413 | *h_errnop = NETDB_INTERNAL; | |
414 | return NSS_STATUS_TRYAGAIN; | |
415 | } | |
416 | else | |
417 | { | |
418 | *h_errnop = HOST_NOT_FOUND; | |
419 | return NSS_STATUS_NOTFOUND; | |
420 | } | |
421 | } | |
422 | ||
423 | *h_errnop = NETDB_SUCCESS; | |
424 | return NSS_STATUS_SUCCESS; | |
425 | } | |
1e275b9e | 426 | |
1eb946b9 | 427 | |
1e275b9e | 428 | enum nss_status |
1eb946b9 UD |
429 | _nss_nis_gethostbyname4_r (const char *name, struct gaih_addrtuple **pat, |
430 | char *buffer, size_t buflen, int *errnop, | |
431 | int *herrnop, int32_t *ttlp) | |
1e275b9e | 432 | { |
1eb946b9 UD |
433 | char *domain; |
434 | if (yp_get_default_domain (&domain)) | |
a682a1bf UD |
435 | { |
436 | *herrnop = NO_DATA; | |
437 | return NSS_STATUS_UNAVAIL; | |
438 | } | |
1eb946b9 UD |
439 | |
440 | /* Convert name to lowercase. */ | |
441 | size_t namlen = strlen (name); | |
315eb1d8 AS |
442 | /* Limit name length to the maximum size of an RPC packet. */ |
443 | if (namlen > UDPMSGSIZE) | |
444 | { | |
445 | *errnop = ERANGE; | |
446 | return NSS_STATUS_UNAVAIL; | |
447 | } | |
448 | ||
1eb946b9 UD |
449 | char name2[namlen + 1]; |
450 | size_t i; | |
451 | ||
452 | for (i = 0; i < namlen; ++i) | |
453 | name2[i] = tolower (name[i]); | |
454 | name2[i] = '\0'; | |
455 | ||
456 | char *result; | |
457 | int len; | |
458 | int yperr = yp_match (domain, "hosts.byname", name2, namlen, &result, &len); | |
459 | ||
a1ffb40e | 460 | if (__glibc_unlikely (yperr != YPERR_SUCCESS)) |
1eb946b9 UD |
461 | { |
462 | enum nss_status retval = yperr2nss (yperr); | |
463 | ||
464 | if (retval == NSS_STATUS_TRYAGAIN) | |
465 | { | |
466 | *herrnop = TRY_AGAIN; | |
467 | *errnop = errno; | |
468 | } | |
469 | if (retval == NSS_STATUS_NOTFOUND) | |
470 | *herrnop = HOST_NOT_FOUND; | |
471 | return retval; | |
472 | } | |
473 | ||
1eb946b9 UD |
474 | if (*pat == NULL) |
475 | { | |
476 | uintptr_t pad = (-(uintptr_t) buffer | |
477 | % __alignof__ (struct gaih_addrtuple)); | |
478 | buffer += pad; | |
479 | buflen = buflen > pad ? buflen - pad : 0; | |
480 | ||
a1ffb40e | 481 | if (__glibc_unlikely (buflen < sizeof (struct gaih_addrtuple))) |
1eb946b9 UD |
482 | { |
483 | erange: | |
484 | free (result); | |
485 | *errnop = ERANGE; | |
486 | *herrnop = NETDB_INTERNAL; | |
487 | return NSS_STATUS_TRYAGAIN; | |
488 | } | |
489 | ||
490 | *pat = (struct gaih_addrtuple *) buffer; | |
491 | buffer += sizeof (struct gaih_addrtuple); | |
492 | buflen -= sizeof (struct gaih_addrtuple); | |
493 | } | |
494 | ||
e87946cc UD |
495 | uintptr_t pad = -(uintptr_t) buffer % __alignof__ (struct parser_data); |
496 | buffer += pad; | |
497 | ||
498 | struct parser_data *data = (void *) buffer; | |
499 | ||
a1ffb40e | 500 | if (__glibc_unlikely (buflen < sizeof *data + 1 + pad)) |
1eb946b9 | 501 | goto erange; |
e87946cc UD |
502 | buflen -= pad; |
503 | ||
504 | struct hostent host; | |
ec255a97 | 505 | int parse_res = parse_line (result, &host, data, buflen, errnop, AF_UNSPEC); |
a1ffb40e | 506 | if (__glibc_unlikely (parse_res < 1)) |
e87946cc UD |
507 | { |
508 | if (parse_res == -1) | |
509 | { | |
510 | *herrnop = NETDB_INTERNAL; | |
511 | return NSS_STATUS_TRYAGAIN; | |
512 | } | |
513 | else | |
514 | { | |
515 | *herrnop = HOST_NOT_FOUND; | |
516 | return NSS_STATUS_NOTFOUND; | |
517 | } | |
518 | } | |
519 | ||
520 | (*pat)->next = NULL; | |
1eb946b9 UD |
521 | (*pat)->family = host.h_addrtype; |
522 | memcpy ((*pat)->addr, host.h_addr_list[0], host.h_length); | |
523 | (*pat)->scopeid = 0; | |
524 | assert (host.h_addr_list[1] == NULL); | |
525 | ||
e87946cc UD |
526 | /* Undo the alignment for parser_data. */ |
527 | buffer -= pad; | |
528 | buflen += pad; | |
529 | ||
530 | size_t h_name_len = strlen (host.h_name) + 1; | |
531 | if (h_name_len >= buflen) | |
532 | goto erange; | |
905ef0da | 533 | (*pat)->name = memcpy (buffer, host.h_name, h_name_len); |
e87946cc | 534 | |
1eb946b9 UD |
535 | free (result); |
536 | ||
537 | return NSS_STATUS_SUCCESS; | |
1e275b9e | 538 | } |