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