]>
Commit | Line | Data |
---|---|---|
d4697bc9 | 1 | /* Copyright (C) 1996-2014 Free Software Foundation, Inc. |
6259ec0d UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1996. | |
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 | |
4eaa9bb4 | 19 | #include <assert.h> |
a334319f UD |
20 | #include <ctype.h> |
21 | #include <errno.h> | |
4eaa9bb4 UD |
22 | #include <nss.h> |
23 | #include <pwd.h> | |
6259ec0d | 24 | #include <string.h> |
5107cf1d | 25 | #include <bits/libc-lock.h> |
6259ec0d UD |
26 | #include <rpcsvc/yp.h> |
27 | #include <rpcsvc/ypclnt.h> | |
28 | ||
29 | #include "nss-nis.h" | |
4eaa9bb4 | 30 | #include <libnsl.h> |
6259ec0d | 31 | |
7e3be507 UD |
32 | /* Get the declaration of the parser function. */ |
33 | #define ENTNAME pwent | |
34 | #define STRUCTURE passwd | |
35 | #define EXTERN_PARSER | |
cf29ffbe | 36 | #include <nss/nss_files/files-parse.c> |
7e3be507 | 37 | |
6259ec0d UD |
38 | /* Protect global state against multiple changers */ |
39 | __libc_lock_define_initialized (static, lock) | |
40 | ||
71170aa0 | 41 | static bool new_start = true; |
fc9f33e3 UD |
42 | static char *oldkey; |
43 | static int oldkeylen; | |
4eaa9bb4 UD |
44 | static intern_t intern; |
45 | ||
46 | ||
e0d4e91d UD |
47 | int |
48 | _nis_saveit (int instatus, char *inkey, int inkeylen, char *inval, | |
49 | int invallen, char *indata) | |
4eaa9bb4 | 50 | { |
e0d4e91d UD |
51 | intern_t *intern = (intern_t *) indata; |
52 | ||
4eaa9bb4 UD |
53 | if (instatus != YP_TRUE) |
54 | return 1; | |
55 | ||
56 | if (inkey && inkeylen > 0 && inval && invallen > 0) | |
57 | { | |
e0d4e91d | 58 | struct response_t *bucket = intern->next; |
4eaa9bb4 UD |
59 | |
60 | if (__builtin_expect (bucket == NULL, 0)) | |
61 | { | |
62 | #define MINSIZE 4096 - 4 * sizeof (void *) | |
63 | const size_t minsize = MAX (MINSIZE, 2 * (invallen + 1)); | |
64 | bucket = malloc (sizeof (struct response_t) + minsize); | |
65 | if (bucket == NULL) | |
66 | /* We have no error code for out of memory. */ | |
67 | return 1; | |
68 | ||
69 | bucket->next = NULL; | |
70 | bucket->size = minsize; | |
e0d4e91d UD |
71 | intern->start = intern->next = bucket; |
72 | intern->offset = 0; | |
4eaa9bb4 | 73 | } |
e0d4e91d | 74 | else if (__builtin_expect (invallen + 1 > bucket->size - intern->offset, |
4eaa9bb4 UD |
75 | 0)) |
76 | { | |
77 | /* We need a new (larger) buffer. */ | |
78 | const size_t newsize = 2 * MAX (bucket->size, invallen + 1); | |
79 | struct response_t *newp = malloc (sizeof (struct response_t) | |
80 | + newsize); | |
81 | if (newp == NULL) | |
82 | /* We have no error code for out of memory. */ | |
83 | return 1; | |
84 | ||
85 | /* Mark the old bucket as full. */ | |
e0d4e91d | 86 | bucket->size = intern->offset; |
4eaa9bb4 UD |
87 | |
88 | newp->next = NULL; | |
89 | newp->size = newsize; | |
e0d4e91d UD |
90 | bucket = intern->next = bucket->next = newp; |
91 | intern->offset = 0; | |
4eaa9bb4 UD |
92 | } |
93 | ||
e0d4e91d | 94 | char *p = mempcpy (&bucket->mem[intern->offset], inval, invallen); |
4eaa9bb4 UD |
95 | if (__builtin_expect (p[-1] != '\0', 0)) |
96 | { | |
97 | *p = '\0'; | |
98 | ++invallen; | |
99 | } | |
e0d4e91d | 100 | intern->offset += invallen; |
4eaa9bb4 | 101 | } |
0ecb606c | 102 | |
4eaa9bb4 UD |
103 | return 0; |
104 | } | |
105 | ||
106 | ||
107 | static void | |
108 | internal_nis_endpwent (void) | |
109 | { | |
71170aa0 UD |
110 | new_start = true; |
111 | free (oldkey); | |
112 | oldkey = NULL; | |
113 | oldkeylen = 0; | |
6259ec0d | 114 | |
233a182b | 115 | struct response_t *curr = intern.start; |
4eaa9bb4 UD |
116 | |
117 | while (curr != NULL) | |
118 | { | |
119 | struct response_t *last = curr; | |
120 | curr = curr->next; | |
121 | free (last); | |
122 | } | |
123 | ||
124 | intern.next = intern.start = NULL; | |
125 | } | |
126 | ||
127 | ||
128 | enum nss_status | |
129 | _nss_nis_endpwent (void) | |
130 | { | |
131 | __libc_lock_lock (lock); | |
132 | ||
133 | internal_nis_endpwent (); | |
134 | ||
6259ec0d UD |
135 | __libc_lock_unlock (lock); |
136 | ||
137 | return NSS_STATUS_SUCCESS; | |
138 | } | |
4eaa9bb4 UD |
139 | |
140 | ||
141 | enum nss_status | |
142 | internal_nis_setpwent (void) | |
143 | { | |
144 | /* We have to read all the data now. */ | |
145 | char *domain; | |
146 | if (__builtin_expect (yp_get_default_domain (&domain), 0)) | |
147 | return NSS_STATUS_UNAVAIL; | |
148 | ||
149 | struct ypall_callback ypcb; | |
150 | ||
e0d4e91d UD |
151 | ypcb.foreach = _nis_saveit; |
152 | ypcb.data = (char *) &intern; | |
4eaa9bb4 UD |
153 | enum nss_status status = yperr2nss (yp_all (domain, "passwd.byname", &ypcb)); |
154 | ||
155 | ||
156 | /* Mark the last buffer as full. */ | |
157 | if (intern.next != NULL) | |
158 | intern.next->size = intern.offset; | |
159 | ||
160 | intern.next = intern.start; | |
161 | intern.offset = 0; | |
162 | ||
163 | return status; | |
164 | } | |
165 | ||
166 | ||
167 | enum nss_status | |
168 | _nss_nis_setpwent (int stayopen) | |
169 | { | |
170 | enum nss_status result = NSS_STATUS_SUCCESS; | |
171 | ||
172 | __libc_lock_lock (lock); | |
173 | ||
174 | internal_nis_endpwent (); | |
175 | ||
176 | if (_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) | |
177 | result = internal_nis_setpwent (); | |
178 | ||
179 | __libc_lock_unlock (lock); | |
180 | ||
181 | return result; | |
182 | } | |
183 | ||
6259ec0d UD |
184 | |
185 | static enum nss_status | |
d71b808a UD |
186 | internal_nis_getpwent_r (struct passwd *pwd, char *buffer, size_t buflen, |
187 | int *errnop) | |
6259ec0d | 188 | { |
4eaa9bb4 UD |
189 | /* If we read the entire database at setpwent time we just iterate |
190 | over the data we have in memory. */ | |
191 | bool batch_read = intern.start != NULL; | |
192 | ||
193 | char *domain = NULL; | |
194 | if (!batch_read && __builtin_expect (yp_get_default_domain (&domain), 0)) | |
6259ec0d UD |
195 | return NSS_STATUS_UNAVAIL; |
196 | ||
197 | /* Get the next entry until we found a correct one. */ | |
ab9a9ff8 | 198 | int parse_res; |
6259ec0d UD |
199 | do |
200 | { | |
ab9a9ff8 UD |
201 | char *result; |
202 | char *outkey; | |
203 | int len; | |
204 | int keylen; | |
0ecb606c | 205 | |
4eaa9bb4 UD |
206 | if (batch_read) |
207 | { | |
208 | struct response_t *bucket; | |
209 | ||
210 | handle_batch_read: | |
211 | bucket = intern.next; | |
212 | ||
213 | if (__builtin_expect (intern.offset >= bucket->size, 0)) | |
214 | { | |
215 | if (bucket->next == NULL) | |
216 | return NSS_STATUS_NOTFOUND; | |
217 | ||
218 | /* We look at all the content in the current bucket. Go on | |
219 | to the next. */ | |
220 | bucket = intern.next = bucket->next; | |
221 | intern.offset = 0; | |
222 | } | |
223 | ||
224 | for (result = &bucket->mem[intern.offset]; isspace (*result); | |
225 | ++result) | |
226 | ++intern.offset; | |
227 | ||
228 | len = strlen (result); | |
229 | } | |
6259ec0d | 230 | else |
4eaa9bb4 UD |
231 | { |
232 | int yperr; | |
6259ec0d | 233 | |
4eaa9bb4 UD |
234 | if (new_start) |
235 | { | |
236 | /* Maybe we should read the database in one piece. */ | |
237 | if ((_nsl_default_nss () & NSS_FLAG_SETENT_BATCH_READ) | |
238 | && internal_nis_setpwent () == NSS_STATUS_SUCCESS | |
239 | && intern.start != NULL) | |
240 | { | |
241 | batch_read = true; | |
242 | goto handle_batch_read; | |
243 | } | |
244 | ||
245 | yperr = yp_first (domain, "passwd.byname", &outkey, &keylen, | |
246 | &result, &len); | |
247 | } | |
248 | else | |
249 | yperr = yp_next (domain, "passwd.byname", oldkey, oldkeylen, | |
250 | &outkey, &keylen, &result, &len); | |
251 | ||
252 | if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) | |
253 | { | |
254 | enum nss_status retval = yperr2nss (yperr); | |
ab9a9ff8 | 255 | |
4eaa9bb4 UD |
256 | if (retval == NSS_STATUS_TRYAGAIN) |
257 | *errnop = errno; | |
258 | return retval; | |
259 | } | |
260 | } | |
6259ec0d | 261 | |
8eaaffde | 262 | /* Check for adjunct style secret passwords. They can be |
71170aa0 UD |
263 | recognized by a password starting with "##". We do not use |
264 | it if the passwd.adjunct.byname table is supposed to be used | |
265 | as a shadow.byname replacement. */ | |
ab9a9ff8 UD |
266 | char *p = strchr (result, ':'); |
267 | size_t namelen; | |
268 | char *result2; | |
269 | int len2; | |
71170aa0 UD |
270 | if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 |
271 | && p != NULL /* This better should be true in all cases. */ | |
8eaaffde UD |
272 | && p[1] == '#' && p[2] == '#' |
273 | && (namelen = p - result, | |
274 | yp_match (domain, "passwd.adjunct.byname", result, namelen, | |
275 | &result2, &len2)) == YPERR_SUCCESS) | |
276 | { | |
71170aa0 | 277 | /* We found a passwd.adjunct.byname entry. Merge encrypted |
8eaaffde UD |
278 | password therein into original result. */ |
279 | char *encrypted = strchr (result2, ':'); | |
280 | char *endp; | |
281 | size_t restlen; | |
282 | ||
7ef90c15 | 283 | if (encrypted == NULL |
8eaaffde UD |
284 | || (endp = strchr (++encrypted, ':')) == NULL |
285 | || (p = strchr (p + 1, ':')) == NULL) | |
286 | { | |
287 | /* Invalid format of the entry. This never should happen | |
288 | unless the data from which the NIS table is generated is | |
289 | wrong. We simply ignore it. */ | |
290 | free (result2); | |
291 | goto non_adjunct; | |
292 | } | |
293 | ||
294 | restlen = len - (p - result); | |
ab9a9ff8 UD |
295 | if (__builtin_expect ((size_t) (namelen + (endp - encrypted) |
296 | + restlen + 2) > buflen, 0)) | |
8eaaffde UD |
297 | { |
298 | free (result2); | |
299 | free (result); | |
300 | *errnop = ERANGE; | |
301 | return NSS_STATUS_TRYAGAIN; | |
302 | } | |
303 | ||
4eaa9bb4 UD |
304 | mempcpy (mempcpy (mempcpy (mempcpy (buffer, result, namelen), |
305 | ":", 1), | |
306 | encrypted, endp - encrypted), | |
307 | p, restlen + 1); | |
8eaaffde UD |
308 | p = buffer; |
309 | ||
310 | free (result2); | |
311 | } | |
312 | else | |
313 | { | |
314 | non_adjunct: | |
ab9a9ff8 | 315 | if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) |
8eaaffde UD |
316 | { |
317 | free (result); | |
318 | *errnop = ERANGE; | |
319 | return NSS_STATUS_TRYAGAIN; | |
320 | } | |
321 | ||
4eaa9bb4 UD |
322 | p = buffer; |
323 | *((char *) mempcpy (buffer, result, len)) = '\0'; | |
8eaaffde | 324 | } |
6259ec0d | 325 | |
6259ec0d | 326 | while (isspace (*p)) |
71170aa0 | 327 | ++p; |
4eaa9bb4 UD |
328 | if (!batch_read) |
329 | free (result); | |
6259ec0d | 330 | |
ab9a9ff8 UD |
331 | parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, |
332 | errnop); | |
333 | if (__builtin_expect (parse_res == -1, 0)) | |
60c96635 | 334 | { |
1e528c6e UD |
335 | if (!batch_read) |
336 | free (outkey); | |
d71b808a | 337 | *errnop = ERANGE; |
60c96635 UD |
338 | return NSS_STATUS_TRYAGAIN; |
339 | } | |
6259ec0d | 340 | |
4eaa9bb4 UD |
341 | if (batch_read) |
342 | intern.offset += len + 1; | |
343 | else | |
344 | { | |
345 | free (oldkey); | |
346 | oldkey = outkey; | |
347 | oldkeylen = keylen; | |
71170aa0 | 348 | new_start = false; |
4eaa9bb4 | 349 | } |
6259ec0d | 350 | } |
60c96635 | 351 | while (parse_res < 1); |
6259ec0d UD |
352 | |
353 | return NSS_STATUS_SUCCESS; | |
354 | } | |
355 | ||
356 | enum nss_status | |
d71b808a UD |
357 | _nss_nis_getpwent_r (struct passwd *result, char *buffer, size_t buflen, |
358 | int *errnop) | |
6259ec0d UD |
359 | { |
360 | int status; | |
361 | ||
362 | __libc_lock_lock (lock); | |
363 | ||
d71b808a | 364 | status = internal_nis_getpwent_r (result, buffer, buflen, errnop); |
6259ec0d UD |
365 | |
366 | __libc_lock_unlock (lock); | |
367 | ||
368 | return status; | |
369 | } | |
370 | ||
371 | enum nss_status | |
372 | _nss_nis_getpwnam_r (const char *name, struct passwd *pwd, | |
d71b808a | 373 | char *buffer, size_t buflen, int *errnop) |
6259ec0d | 374 | { |
6259ec0d UD |
375 | if (name == NULL) |
376 | { | |
ac9f45cf | 377 | *errnop = EINVAL; |
6259ec0d UD |
378 | return NSS_STATUS_UNAVAIL; |
379 | } | |
380 | ||
ab9a9ff8 UD |
381 | char *domain; |
382 | if (__builtin_expect (yp_get_default_domain (&domain), 0)) | |
6259ec0d UD |
383 | return NSS_STATUS_UNAVAIL; |
384 | ||
ab9a9ff8 | 385 | size_t namelen = strlen (name); |
8eaaffde | 386 | |
ab9a9ff8 UD |
387 | char *result; |
388 | int len; | |
389 | int yperr = yp_match (domain, "passwd.byname", name, namelen, &result, &len); | |
6259ec0d | 390 | |
ab9a9ff8 | 391 | if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) |
6259ec0d | 392 | { |
ab9a9ff8 UD |
393 | enum nss_status retval = yperr2nss (yperr); |
394 | ||
34816665 | 395 | if (retval == NSS_STATUS_TRYAGAIN) |
d71b808a | 396 | *errnop = errno; |
6259ec0d UD |
397 | return retval; |
398 | } | |
399 | ||
8eaaffde | 400 | /* Check for adjunct style secret passwords. They can be recognized |
71170aa0 UD |
401 | by a password starting with "##". We do not use it if the |
402 | passwd.adjunct.byname table is supposed to be used as a shadow.byname | |
403 | replacement. */ | |
ab9a9ff8 UD |
404 | char *result2; |
405 | int len2; | |
406 | char *p = strchr (result, ':'); | |
71170aa0 UD |
407 | if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 |
408 | && p != NULL /* This better should be true in all cases. */ | |
8eaaffde UD |
409 | && p[1] == '#' && p[2] == '#' |
410 | && yp_match (domain, "passwd.adjunct.byname", name, namelen, | |
411 | &result2, &len2) == YPERR_SUCCESS) | |
6259ec0d | 412 | { |
71170aa0 | 413 | /* We found a passwd.adjunct.byname entry. Merge encrypted password |
8eaaffde UD |
414 | therein into original result. */ |
415 | char *encrypted = strchr (result2, ':'); | |
416 | char *endp; | |
8eaaffde | 417 | |
85c165be | 418 | if (encrypted == NULL |
8eaaffde UD |
419 | || (endp = strchr (++encrypted, ':')) == NULL |
420 | || (p = strchr (p + 1, ':')) == NULL) | |
421 | { | |
422 | /* Invalid format of the entry. This never should happen | |
423 | unless the data from which the NIS table is generated is | |
424 | wrong. We simply ignore it. */ | |
425 | free (result2); | |
426 | goto non_adjunct; | |
427 | } | |
428 | ||
ab9a9ff8 UD |
429 | size_t restlen = len - (p - result); |
430 | if (__builtin_expect ((size_t) (namelen + (endp - encrypted) | |
431 | + restlen + 2) > buflen, 0)) | |
8eaaffde UD |
432 | { |
433 | free (result2); | |
434 | free (result); | |
435 | *errnop = ERANGE; | |
436 | return NSS_STATUS_TRYAGAIN; | |
437 | } | |
438 | ||
439 | __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, name, namelen), | |
440 | ":", 1), | |
441 | encrypted, endp - encrypted), | |
442 | p, restlen + 1); | |
443 | p = buffer; | |
444 | ||
445 | free (result2); | |
446 | } | |
447 | else | |
448 | { | |
449 | non_adjunct: | |
ab9a9ff8 | 450 | if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) |
8eaaffde UD |
451 | { |
452 | free (result); | |
453 | *errnop = ERANGE; | |
454 | return NSS_STATUS_TRYAGAIN; | |
455 | } | |
456 | ||
457 | p = strncpy (buffer, result, len); | |
458 | buffer[len] = '\0'; | |
6259ec0d UD |
459 | } |
460 | ||
6259ec0d UD |
461 | while (isspace (*p)) |
462 | ++p; | |
463 | free (result); | |
464 | ||
ab9a9ff8 UD |
465 | int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, |
466 | errnop); | |
467 | if (__builtin_expect (parse_res < 1, 0)) | |
6259ec0d | 468 | { |
60c96635 | 469 | if (parse_res == -1) |
71170aa0 | 470 | return NSS_STATUS_TRYAGAIN; |
6259ec0d | 471 | else |
34816665 | 472 | return NSS_STATUS_NOTFOUND; |
6259ec0d UD |
473 | } |
474 | else | |
475 | return NSS_STATUS_SUCCESS; | |
476 | } | |
477 | ||
478 | enum nss_status | |
479 | _nss_nis_getpwuid_r (uid_t uid, struct passwd *pwd, | |
d71b808a | 480 | char *buffer, size_t buflen, int *errnop) |
6259ec0d | 481 | { |
ab9a9ff8 UD |
482 | char *domain; |
483 | if (__builtin_expect (yp_get_default_domain (&domain), 0)) | |
6259ec0d UD |
484 | return NSS_STATUS_UNAVAIL; |
485 | ||
ab9a9ff8 UD |
486 | char buf[32]; |
487 | int nlen = snprintf (buf, sizeof (buf), "%lu", (unsigned long int) uid); | |
6259ec0d | 488 | |
ab9a9ff8 UD |
489 | char *result; |
490 | int len; | |
491 | int yperr = yp_match (domain, "passwd.byuid", buf, nlen, &result, &len); | |
6259ec0d | 492 | |
ab9a9ff8 | 493 | if (__builtin_expect (yperr != YPERR_SUCCESS, 0)) |
6259ec0d | 494 | { |
ab9a9ff8 UD |
495 | enum nss_status retval = yperr2nss (yperr); |
496 | ||
34816665 | 497 | if (retval == NSS_STATUS_TRYAGAIN) |
d71b808a | 498 | *errnop = errno; |
6259ec0d UD |
499 | return retval; |
500 | } | |
501 | ||
8eaaffde | 502 | /* Check for adjunct style secret passwords. They can be recognized |
71170aa0 UD |
503 | by a password starting with "##". We do not use it if the |
504 | passwd.adjunct.byname table is supposed to be used as a shadow.byname | |
505 | replacement. */ | |
ab9a9ff8 UD |
506 | char *result2; |
507 | int len2; | |
508 | size_t namelen; | |
509 | char *p = strchr (result, ':'); | |
71170aa0 UD |
510 | if ((_nsl_default_nss () & NSS_FLAG_ADJUNCT_AS_SHADOW) == 0 |
511 | && p != NULL /* This better should be true in all cases. */ | |
8eaaffde UD |
512 | && p[1] == '#' && p[2] == '#' |
513 | && (namelen = p - result, | |
514 | yp_match (domain, "passwd.adjunct.byname", result, namelen, | |
515 | &result2, &len2)) == YPERR_SUCCESS) | |
6259ec0d | 516 | { |
71170aa0 | 517 | /* We found a passwd.adjunct.byname entry. Merge encrypted password |
8eaaffde UD |
518 | therein into original result. */ |
519 | char *encrypted = strchr (result2, ':'); | |
520 | char *endp; | |
521 | size_t restlen; | |
522 | ||
85c165be | 523 | if (encrypted == NULL |
8eaaffde UD |
524 | || (endp = strchr (++encrypted, ':')) == NULL |
525 | || (p = strchr (p + 1, ':')) == NULL) | |
526 | { | |
527 | /* Invalid format of the entry. This never should happen | |
528 | unless the data from which the NIS table is generated is | |
529 | wrong. We simply ignore it. */ | |
530 | free (result2); | |
531 | goto non_adjunct; | |
532 | } | |
533 | ||
534 | restlen = len - (p - result); | |
ab9a9ff8 UD |
535 | if (__builtin_expect ((size_t) (namelen + (endp - encrypted) |
536 | + restlen + 2) > buflen, 0)) | |
8eaaffde UD |
537 | { |
538 | free (result2); | |
539 | free (result); | |
540 | *errnop = ERANGE; | |
541 | return NSS_STATUS_TRYAGAIN; | |
542 | } | |
543 | ||
544 | __mempcpy (__mempcpy (__mempcpy (__mempcpy (buffer, result, namelen), | |
545 | ":", 1), | |
546 | encrypted, endp - encrypted), | |
547 | p, restlen + 1); | |
548 | p = buffer; | |
549 | ||
550 | free (result2); | |
551 | } | |
552 | else | |
553 | { | |
554 | non_adjunct: | |
ab9a9ff8 | 555 | if (__builtin_expect ((size_t) (len + 1) > buflen, 0)) |
8eaaffde UD |
556 | { |
557 | free (result); | |
558 | *errnop = ERANGE; | |
559 | return NSS_STATUS_TRYAGAIN; | |
560 | } | |
561 | ||
562 | p = strncpy (buffer, result, len); | |
563 | buffer[len] = '\0'; | |
6259ec0d UD |
564 | } |
565 | ||
6259ec0d UD |
566 | while (isspace (*p)) |
567 | ++p; | |
568 | free (result); | |
569 | ||
ab9a9ff8 UD |
570 | int parse_res = _nss_files_parse_pwent (p, pwd, (void *) buffer, buflen, |
571 | errnop); | |
572 | if (__builtin_expect (parse_res < 1, 0)) | |
6259ec0d | 573 | { |
60c96635 | 574 | if (parse_res == -1) |
71170aa0 | 575 | return NSS_STATUS_TRYAGAIN; |
0c6cee5d | 576 | else |
34816665 | 577 | return NSS_STATUS_NOTFOUND; |
6259ec0d UD |
578 | } |
579 | else | |
580 | return NSS_STATUS_SUCCESS; | |
581 | } |