/*
- * Copyright (c) 2005, 2008, 2010-2011 Todd C. Miller <Todd.Miller@courtesan.com>
+ * Copyright (c) 2005, 2008, 2010-2013
+ * Todd C. Miller <Todd.Miller@courtesan.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
#include <config.h>
#include <sys/types.h>
-#include <sys/param.h>
#include <stdio.h>
#ifdef STDC_HEADERS
# include <stdlib.h>
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif /* HAVE_STRINGS_H */
+#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#undef GRMEM_MAX
#define GRMEM_MAX 200
+#ifndef UID_MAX
+# define UID_MAX 0xffffffffU
+#endif
+
+#ifndef GID_MAX
+# define GID_MAX UID_MAX
+#endif
+
static FILE *pwf;
static const char *pwfile = "/etc/passwd";
static int pw_stayopen;
static struct passwd pw;
static char pwbuf[LINE_MAX];
size_t len;
- char *cp, *colon;
+ unsigned long id;
+ char *cp, *colon, *ep;
+next_entry:
if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
return NULL;
zero_bytes(&pw, sizeof(pw));
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
pw.pw_name = cp;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
pw.pw_passwd = cp;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
- pw.pw_uid = atoi(cp);
+ id = strtoul(cp, &ep, 10);
+ if (*cp == '\0' || *ep != '\0')
+ goto next_entry;
+ if (id > UID_MAX || (id == ULONG_MAX && errno == ERANGE))
+ goto next_entry;
+ pw.pw_uid = (uid_t)id;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
- pw.pw_gid = atoi(cp);
+ id = strtoul(cp, &ep, 10);
+ if (*cp == '\0' || *ep != '\0')
+ goto next_entry;
+ if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
+ goto next_entry;
+ pw.pw_gid = (gid_t)id;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
pw.pw_gecos = cp;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
pw.pw_dir = cp;
pw.pw_shell = colon;
static struct group gr;
static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
size_t len;
- char *cp, *colon;
+ unsigned long id;
+ char *cp, *colon, *ep;
int n;
+next_entry:
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
return NULL;
zero_bytes(&gr, sizeof(gr));
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
gr.gr_name = cp;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
gr.gr_passwd = cp;
if ((colon = strchr(cp = colon, ':')) == NULL)
- return NULL;
+ goto next_entry;
*colon++ = '\0';
- gr.gr_gid = atoi(cp);
+ id = strtoul(cp, &ep, 10);
+ if (*cp == '\0' || *ep != '\0')
+ goto next_entry;
+ if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
+ goto next_entry;
+ gr.gr_gid = (gid_t)id;
len = strlen(colon);
if (len > 0 && colon[len - 1] == '\n')
colon[len - 1] = '\0';