(root)/
glibc-2.38/
nss/
tst-nss-getpwent.c
       1  /* Copyright (C) 2015-2023 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
      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>