aboutsummaryrefslogtreecommitdiff
path: root/pwd
diff options
context:
space:
mode:
Diffstat (limited to 'pwd')
-rw-r--r--pwd/tst-getpw.c83
1 files changed, 77 insertions, 6 deletions
diff --git a/pwd/tst-getpw.c b/pwd/tst-getpw.c
index 059c9e0..e3e101b 100644
--- a/pwd/tst-getpw.c
+++ b/pwd/tst-getpw.c
@@ -15,28 +15,99 @@
License along with the GNU C Library; if not, see
<http://www.gnu.org/licenses/>. */
+#include <stdio.h>
#include <pwd.h>
+#include <errno.h>
+#include <stdbool.h>
+
+/* We want to test getpw by calling it with a uid that does
+ exist and one that doesn't exist. We track if we've met those
+ conditions and exit. We also track if we've failed due to lack
+ of memory. That constitutes all of the standard failure cases. */
+bool seen_hit;
+bool seen_miss;
+bool seen_oom;
+
+/* How many errors we've had while running the test. */
+int errors;
static void
check (uid_t uid)
{
+ int ret;
char buf[1024];
- (void) getpw (uid, buf);
+ ret = getpw (uid, buf);
+
+ /* Successfully read a password line. */
+ if (ret == 0 && !seen_hit)
+ {
+ printf ("PASS: Read a password line given a uid.\n");
+ seen_hit = true;
+ }
+
+ /* Failed to read a password line. Why? */
+ if (ret == -1)
+ {
+ /* No entry? Technically the errno could be any number
+ of values including ESRCH, EBADP or EPERM depending
+ on the quality of the nss module that implements the
+ underlying lookup. It should be 0 for getpw.*/
+ if (errno == 0 && !seen_miss)
+ {
+ printf ("PASS: Found an invalid uid.\n");
+ seen_miss = true;
+ return;
+ }
+
+ /* Out of memory? */
+ if (errno == ENOMEM && !seen_oom)
+ {
+ printf ("FAIL: Failed with ENOMEM.\n");
+ seen_oom = true;
+ errors++;
+ }
+
+ /* We don't expect any other values for errno. */
+ if (errno != ENOMEM && errno != 0)
+ errors++;
+ }
}
static int
do_test (void)
{
+ int ret;
uid_t uid;
- /* Just call it a different number of times the range should be
- large enough to find some existing and some non existing uids. */
+ /* Should return -1 and set errnot to EINVAL. */
+ ret = getpw (0, NULL);
+ if (ret == -1 && errno == EINVAL)
+ {
+ printf ("PASS: NULL buffer returns -1 and sets errno to EINVAL.\n");
+ }
+ else
+ {
+ printf ("FAIL: NULL buffer did not return -1 or set errno to EINVAL.\n");
+ errors++;
+ }
+
+ /* Look for one matching uid, one non-found uid and then stop.
+ Set an upper limit at the 16-bit UID mark; no need to go farther. */
+ for (uid = 0; uid < ((uid_t) 65535); ++uid)
+ {
+ check (uid);
+ if (seen_miss && seen_hit)
+ break;
+ }
+
+ if (!seen_hit)
+ printf ("FAIL: Did not read even one password line given a uid.\n");
- for (uid = 0; uid < 2000; ++uid)
- check (uid);
+ if (!seen_miss)
+ printf ("FAIL: Did not find even one invalid uid.\n");
- return 0;
+ return errors;
}
#define TEST_FUNCTION do_test ()