1 /* Copyright (C) 2015-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <nss.h>
19 #include <pwd.h>
20 #include <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include <support/support.h>
26 
27 int
do_test(void)28 do_test (void)
29 {
30   __nss_configure_lookup ("passwd", "files");
31 
32   /* Count the number of entries in the password database, and fetch
33      data from the first and last entries.  */
34   size_t count = 0;
35   struct passwd * pw;
36   char *first_name = NULL;
37   uid_t first_uid = 0;
38   char *last_name = NULL;
39   uid_t last_uid = 0;
40   setpwent ();
41   while ((pw  = getpwent ()) != NULL)
42     {
43       if (first_name == NULL)
44 	{
45 	  first_name = xstrdup (pw->pw_name);
46 	  first_uid = pw->pw_uid;
47 	}
48 
49       free (last_name);
50       last_name = xstrdup (pw->pw_name);
51       last_uid = pw->pw_uid;
52       ++count;
53     }
54   endpwent ();
55 
56   if (count == 0)
57     {
58       printf ("No entries in the password database.\n");
59       return 0;
60     }
61 
62   /* Try again, this time interleaving with name-based and UID-based
63      lookup operations.  The counts do not match if the interleaved
64      lookups affected the enumeration.  */
65   size_t new_count = 0;
66   setpwent ();
67   while ((pw  = getpwent ()) != NULL)
68     {
69       if (new_count == count)
70 	{
71 	  printf ("Additional entry in the password database.\n");
72 	  return 1;
73 	}
74       ++new_count;
75       struct passwd *pw2 = getpwnam (first_name);
76       if (pw2 == NULL)
77 	{
78 	  printf ("getpwnam (%s) failed: %m\n", first_name);
79 	  return 1;
80 	}
81       pw2 = getpwnam (last_name);
82       if (pw2 == NULL)
83 	{
84 	  printf ("getpwnam (%s) failed: %m\n", last_name);
85 	  return 1;
86 	}
87       pw2 = getpwuid (first_uid);
88       if (pw2 == NULL)
89 	{
90 	  printf ("getpwuid (%llu) failed: %m\n",
91 		  (unsigned long long) first_uid);
92 	  return 1;
93 	}
94       pw2 = getpwuid (last_uid);
95       if (pw2 == NULL)
96 	{
97 	  printf ("getpwuid (%llu) failed: %m\n",
98 		  (unsigned long long) last_uid);
99 	  return 1;
100 	}
101     }
102   endpwent ();
103   if (new_count < count)
104     {
105       printf ("Missing entry in the password database.\n");
106       return 1;
107     }
108 
109   return 0;
110 }
111 
112 #define TIMEOUT 300
113 #include <support/test-driver.c>
114