Blame pwd/tst-getpw.c

Packit 6c4009
/* Copyright (C) 1999-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <stdio.h>
Packit 6c4009
#include <pwd.h>
Packit 6c4009
#include <errno.h>
Packit 6c4009
#include <stdbool.h>
Packit 6c4009
Packit 6c4009
/* We want to test getpw by calling it with a uid that does
Packit 6c4009
   exist and one that doesn't exist. We track if we've met those
Packit 6c4009
   conditions and exit. We also track if we've failed due to lack
Packit 6c4009
   of memory. That constitutes all of the standard failure cases.  */
Packit 6c4009
bool seen_hit;
Packit 6c4009
bool seen_miss;
Packit 6c4009
bool seen_oom;
Packit 6c4009
Packit 6c4009
/* How many errors we've had while running the test.  */
Packit 6c4009
int errors;
Packit 6c4009
Packit 6c4009
static void
Packit 6c4009
check (uid_t uid)
Packit 6c4009
{
Packit 6c4009
  int ret;
Packit 6c4009
  char buf[1024];
Packit 6c4009
Packit 6c4009
  ret = getpw (uid, buf);
Packit 6c4009
Packit 6c4009
  /* Successfully read a password line.  */
Packit 6c4009
  if (ret == 0 && !seen_hit)
Packit 6c4009
    {
Packit 6c4009
      printf ("PASS: Read a password line given a uid.\n");
Packit 6c4009
      seen_hit = true;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Failed to read a password line. Why?  */
Packit 6c4009
  if (ret == -1)
Packit 6c4009
    {
Packit 6c4009
      /* No entry?  Technically the errno could be any number
Packit 6c4009
	 of values including ESRCH, EBADP or EPERM depending
Packit 6c4009
	 on the quality of the nss module that implements the
Packit 6c4009
	 underlying lookup. It should be 0 for getpw.*/
Packit 6c4009
      if (errno == 0 && !seen_miss)
Packit 6c4009
	{
Packit 6c4009
	  printf ("PASS: Found an invalid uid.\n");
Packit 6c4009
	  seen_miss = true;
Packit 6c4009
	  return;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* Out of memory?  */
Packit 6c4009
      if (errno == ENOMEM && !seen_oom)
Packit 6c4009
	{
Packit 6c4009
	  printf ("FAIL: Failed with ENOMEM.\n");
Packit 6c4009
	  seen_oom = true;
Packit 6c4009
	  errors++;
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      /* We don't expect any other values for errno.  */
Packit 6c4009
      if (errno != ENOMEM && errno != 0)
Packit 6c4009
	errors++;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
static int
Packit 6c4009
do_test (void)
Packit 6c4009
{
Packit 6c4009
  int ret;
Packit 6c4009
  uid_t uid;
Packit 6c4009
Packit 6c4009
  /* Should return -1 and set errnot to EINVAL.  */
Packit 6c4009
  ret = getpw (0, NULL);
Packit 6c4009
  if (ret == -1 && errno == EINVAL)
Packit 6c4009
    {
Packit 6c4009
      printf ("PASS: NULL buffer returns -1 and sets errno to EINVAL.\n");
Packit 6c4009
    }
Packit 6c4009
  else
Packit 6c4009
    {
Packit 6c4009
      printf ("FAIL: NULL buffer did not return -1 or set errno to EINVAL.\n");
Packit 6c4009
      errors++;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Look for one matching uid, one non-found uid and then stop.
Packit 6c4009
     Set an upper limit at the 16-bit UID mark; no need to go farther.  */
Packit 6c4009
  for (uid = 0; uid < ((uid_t) 65535); ++uid)
Packit 6c4009
    {
Packit 6c4009
      check (uid);
Packit 6c4009
      if (seen_miss && seen_hit)
Packit 6c4009
	break;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  if (!seen_hit)
Packit 6c4009
    printf ("FAIL: Did not read even one password line given a uid.\n");
Packit 6c4009
Packit 6c4009
  if (!seen_miss)
Packit 6c4009
    printf ("FAIL: Did not find even one invalid uid.\n");
Packit 6c4009
Packit 6c4009
  return errors;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#define TEST_FUNCTION do_test ()
Packit 6c4009
#include "../test-skeleton.c"