Use atoid() in more places.

This commit is contained in:
Todd C. Miller
2013-08-07 15:49:03 -06:00
parent 40cb480f07
commit dde7331a0f
5 changed files with 84 additions and 91 deletions

View File

@@ -92,10 +92,6 @@ done:
#elif defined(HAVE_NSS_SEARCH) #elif defined(HAVE_NSS_SEARCH)
#ifndef GID_MAX
# define GID_MAX UID_MAX
#endif
#ifndef ALIGNBYTES #ifndef ALIGNBYTES
# define ALIGNBYTES (sizeof(long) - 1L) # define ALIGNBYTES (sizeof(long) - 1L)
#endif #endif
@@ -104,6 +100,7 @@ done:
#endif #endif
extern void _nss_initf_group(nss_db_params_t *); extern void _nss_initf_group(nss_db_params_t *);
extern id_t atoid(const char *str, const char **errstr);
/* /*
* Convert a groups file string (instr) to a struct group (ent) using * Convert a groups file string (instr) to a struct group (ent) using
@@ -115,8 +112,9 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen)
struct group *grp = ent; struct group *grp = ent;
char *cp, *ep, *fieldsep = buf; char *cp, *ep, *fieldsep = buf;
char **gr_mem, **gr_end; char **gr_mem, **gr_end;
const char *errstr;
int yp = 0; int yp = 0;
unsigned long gid; id_t id;
/* Must at least have space to copy instr -> buf. */ /* Must at least have space to copy instr -> buf. */
if (inlen >= buflen) if (inlen >= buflen)
@@ -150,21 +148,24 @@ str2grp(const char *instr, int inlen, void *ent, char *buf, int buflen)
if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL) if ((fieldsep = strchr(cp = fieldsep, ':')) == NULL)
return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE; return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE;
*fieldsep++ = '\0'; *fieldsep++ = '\0';
gid = strtoul(cp, &ep, 10); errno = 0;
if (*cp == '\0' || *ep != '\0') id = atoid(cp, &errstr);
if (errstr == NULL) {
/*
* A range error is always a fatal error, but ignore garbage
* at the end of YP entries since it has no meaning.
*/
if (errno == ERANGE)
return NSS_STR_PARSE_ERANGE;
return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE; return yp ? NSS_STR_PARSE_SUCCESS : NSS_STR_PARSE_PARSE;
#ifdef GID_NOBODY
if (*cp == '-' && gid != 0) {
/* Negative gids get mapped to nobody on Solaris. */
grp->gr_gid = GID_NOBODY;
} else
#endif
if ((errno == ERANGE && gid == ULONG_MAX) ||
gid > GID_MAX || gid != (gid_t)gid) {
return NSS_STR_PARSE_ERANGE;
} else {
grp->gr_gid = (gid_t)gid;
} }
#ifdef GID_NOBODY
/* Negative gids get mapped to nobody on Solaris. */
if (*cp == '-' && gid != 0)
grp->gr_gid = GID_NOBODY;
else
#endif
grp->gr_gid = (gid_t)id;
/* Store group members, taking care to use proper alignment. */ /* Store group members, taking care to use proper alignment. */
grp->gr_mem = NULL; grp->gr_mem = NULL;

View File

@@ -352,9 +352,10 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
{ {
const char *runas_uid_str = "0", *runas_euid_str = NULL; const char *runas_uid_str = "0", *runas_euid_str = NULL;
const char *runas_gid_str = "0", *runas_egid_str = NULL; const char *runas_gid_str = "0", *runas_egid_str = NULL;
char id[MAX_UID_T_LEN + 2], *ep; const char *errstr;
char idbuf[MAX_UID_T_LEN + 2];
char * const *cur; char * const *cur;
unsigned long ulval; id_t id;
uid_t runas_uid = 0; uid_t runas_uid = 0;
gid_t runas_gid = 0; gid_t runas_gid = 0;
debug_decl(iolog_deserialize_info, SUDO_DEBUG_UTIL) debug_decl(iolog_deserialize_info, SUDO_DEBUG_UTIL)
@@ -470,37 +471,35 @@ iolog_deserialize_info(struct iolog_details *details, char * const user_info[],
if (runas_euid_str != NULL) if (runas_euid_str != NULL)
runas_uid_str = runas_euid_str; runas_uid_str = runas_euid_str;
if (runas_uid_str != NULL) { if (runas_uid_str != NULL) {
errno = 0; id = atoid(runas_uid_str, &errstr);
ulval = strtoul(runas_uid_str, &ep, 0); if (errstr != NULL)
if (*runas_uid_str != '\0' && *ep == '\0' && warningx("runas uid %s: %s", runas_uid_str, _(errstr));
(errno != ERANGE || ulval != ULONG_MAX)) { else
runas_uid = (uid_t)ulval; runas_uid = (uid_t)id;
}
} }
if (runas_egid_str != NULL) if (runas_egid_str != NULL)
runas_gid_str = runas_egid_str; runas_gid_str = runas_egid_str;
if (runas_gid_str != NULL) { if (runas_gid_str != NULL) {
errno = 0; id = atoid(runas_gid_str, &errstr);
ulval = strtoul(runas_gid_str, &ep, 0); if (errstr != NULL)
if (*runas_gid_str != '\0' && *ep == '\0' && warningx("runas gid %s: %s", runas_gid_str, _(errstr));
(errno != ERANGE || ulval != ULONG_MAX)) { else
runas_gid = (gid_t)ulval; runas_gid = (gid_t)id;
}
} }
details->runas_pw = sudo_getpwuid(runas_uid); details->runas_pw = sudo_getpwuid(runas_uid);
if (details->runas_pw == NULL) { if (details->runas_pw == NULL) {
id[0] = '#'; idbuf[0] = '#';
strlcpy(&id[1], runas_uid_str, sizeof(id) - 1); strlcpy(&idbuf[1], runas_uid_str, sizeof(idbuf) - 1);
details->runas_pw = sudo_fakepwnam(id, runas_gid); details->runas_pw = sudo_fakepwnam(idbuf, runas_gid);
} }
if (runas_gid != details->runas_pw->pw_gid) { if (runas_gid != details->runas_pw->pw_gid) {
details->runas_gr = sudo_getgrgid(runas_gid); details->runas_gr = sudo_getgrgid(runas_gid);
if (details->runas_gr == NULL) { if (details->runas_gr == NULL) {
id[0] = '#'; idbuf[0] = '#';
strlcpy(&id[1], runas_gid_str, sizeof(id) - 1); strlcpy(&idbuf[1], runas_gid_str, sizeof(idbuf) - 1);
details->runas_gr = sudo_fakegrnam(id); details->runas_gr = sudo_fakegrnam(idbuf);
} }
} }
debug_return_bool( debug_return_bool(

View File

@@ -123,8 +123,9 @@ getpwent(void)
static struct passwd pw; static struct passwd pw;
static char pwbuf[LINE_MAX]; static char pwbuf[LINE_MAX];
size_t len; size_t len;
unsigned long id; id_t id;
char *cp, *colon, *ep; char *cp, *colon;
const char *errstr;
next_entry: next_entry:
if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL) if ((colon = fgets(pwbuf, sizeof(pwbuf), pwf)) == NULL)
@@ -142,19 +143,15 @@ next_entry:
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
goto next_entry; goto next_entry;
*colon++ = '\0'; *colon++ = '\0';
id = strtoul(cp, &ep, 10); id = atoid(cp, &errstr);
if (*cp == '\0' || *ep != '\0') if (errstr != NULL)
goto next_entry;
if (id > UID_MAX || (id == ULONG_MAX && errno == ERANGE))
goto next_entry; goto next_entry;
pw.pw_uid = (uid_t)id; pw.pw_uid = (uid_t)id;
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
goto next_entry; goto next_entry;
*colon++ = '\0'; *colon++ = '\0';
id = strtoul(cp, &ep, 10); id = atoid(cp, &errstr);
if (*cp == '\0' || *ep != '\0') if (errstr != NULL)
goto next_entry;
if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
goto next_entry; goto next_entry;
pw.pw_gid = (gid_t)id; pw.pw_gid = (gid_t)id;
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
@@ -255,8 +252,9 @@ getgrent(void)
static struct group gr; static struct group gr;
static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1]; static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1];
size_t len; size_t len;
unsigned long id; id_t id;
char *cp, *colon, *ep; char *cp, *colon;
const char *errstr;
int n; int n;
next_entry: next_entry:
@@ -275,10 +273,8 @@ next_entry:
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
goto next_entry; goto next_entry;
*colon++ = '\0'; *colon++ = '\0';
id = strtoul(cp, &ep, 10); id = atoid(cp, &errstr);
if (*cp == '\0' || *ep != '\0') if (errstr != NULL)
goto next_entry;
if (id > GID_MAX || (id == ULONG_MAX && errno == ERANGE))
goto next_entry; goto next_entry;
gr.gr_gid = (gid_t)id; gr.gr_gid = (gid_t)id;
len = strlen(colon); len = strlen(colon);

View File

@@ -530,9 +530,10 @@ static void
command_info_to_details(char * const info[], struct command_details *details) command_info_to_details(char * const info[], struct command_details *details)
{ {
int i; int i;
id_t id;
long lval; long lval;
unsigned long ulval;
char *cp, *ep; char *cp, *ep;
const char *errstr;
debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM) debug_decl(command_info_to_details, SUDO_DEBUG_PCOMM)
memset(details, 0, sizeof(*details)); memset(details, 0, sizeof(*details));
@@ -610,39 +611,33 @@ command_info_to_details(char * const info[], struct command_details *details)
case 'r': case 'r':
if (strncmp("runas_egid=", info[i], sizeof("runas_egid=") - 1) == 0) { if (strncmp("runas_egid=", info[i], sizeof("runas_egid=") - 1) == 0) {
cp = info[i] + sizeof("runas_egid=") - 1; cp = info[i] + sizeof("runas_egid=") - 1;
if (*cp == '\0') id = atoid(cp, &errstr);
break; if (errstr != NULL) {
errno = 0; warningx(_("%s: %s"), info[i], _(errstr));
ulval = strtoul(cp, &ep, 0); } else {
if (*cp != '\0' && *ep == '\0' && details->egid = (gid_t)id;
(errno != ERANGE || ulval != ULONG_MAX)) {
details->egid = (gid_t)ulval;
SET(details->flags, CD_SET_EGID); SET(details->flags, CD_SET_EGID);
} }
break; break;
} }
if (strncmp("runas_euid=", info[i], sizeof("runas_euid=") - 1) == 0) { if (strncmp("runas_euid=", info[i], sizeof("runas_euid=") - 1) == 0) {
cp = info[i] + sizeof("runas_euid=") - 1; cp = info[i] + sizeof("runas_euid=") - 1;
if (*cp == '\0') id = atoid(cp, &errstr);
break; if (errstr != NULL) {
errno = 0; warningx(_("%s: %s"), info[i], _(errstr));
ulval = strtoul(cp, &ep, 0); } else {
if (*cp != '\0' && *ep == '\0' && details->euid = (uid_t)id;
(errno != ERANGE || ulval != ULONG_MAX)) {
details->euid = (uid_t)ulval;
SET(details->flags, CD_SET_EUID); SET(details->flags, CD_SET_EUID);
} }
break; break;
} }
if (strncmp("runas_gid=", info[i], sizeof("runas_gid=") - 1) == 0) { if (strncmp("runas_gid=", info[i], sizeof("runas_gid=") - 1) == 0) {
cp = info[i] + sizeof("runas_gid=") - 1; cp = info[i] + sizeof("runas_gid=") - 1;
if (*cp == '\0') id = atoid(cp, &errstr);
break; if (errstr != NULL) {
errno = 0; warningx(_("%s: %s"), info[i], _(errstr));
ulval = strtoul(cp, &ep, 0); } else {
if (*cp != '\0' && *ep == '\0' && details->gid = (gid_t)id;
(errno != ERANGE || ulval != ULONG_MAX)) {
details->gid = (gid_t)ulval;
SET(details->flags, CD_SET_GID); SET(details->flags, CD_SET_GID);
} }
break; break;
@@ -665,13 +660,12 @@ command_info_to_details(char * const info[], struct command_details *details)
emalloc2(details->ngroups, sizeof(GETGROUPS_T)); emalloc2(details->ngroups, sizeof(GETGROUPS_T));
cp = info[i] + sizeof("runas_groups=") - 1; cp = info[i] + sizeof("runas_groups=") - 1;
for (j = 0; j < details->ngroups;) { for (j = 0; j < details->ngroups;) {
errno = 0; id = atoid(cp, &errstr);
ulval = strtoul(cp, &ep, 0); if (errstr != NULL) {
if (*cp == '\0' || (*ep != ',' && *ep != '\0') || warningx(_("%s: %s"), cp, _(errstr));
(ulval == ULONG_MAX && errno == ERANGE)) {
break; break;
} }
details->groups[j++] = (gid_t)ulval; details->groups[j++] = (gid_t)id;
cp = ep + 1; cp = ep + 1;
} }
details->ngroups = j; details->ngroups = j;
@@ -680,13 +674,11 @@ command_info_to_details(char * const info[], struct command_details *details)
} }
if (strncmp("runas_uid=", info[i], sizeof("runas_uid=") - 1) == 0) { if (strncmp("runas_uid=", info[i], sizeof("runas_uid=") - 1) == 0) {
cp = info[i] + sizeof("runas_uid=") - 1; cp = info[i] + sizeof("runas_uid=") - 1;
if (*cp == '\0') id = atoid(cp, &errstr);
break; if (errstr != NULL) {
errno = 0; warningx(_("%s: %s"), info[i], _(errstr));
ulval = strtoul(cp, &ep, 0); } else {
if (*cp != '\0' && *ep == '\0' && details->uid = (uid_t)id;
(errno != ERANGE || ulval != ULONG_MAX)) {
details->uid = (uid_t)ulval;
SET(details->flags, CD_SET_UID); SET(details->flags, CD_SET_UID);
} }
break; break;
@@ -751,10 +743,12 @@ command_info_to_details(char * const info[], struct command_details *details)
if (*cp == '\0') if (*cp == '\0')
break; break;
errno = 0; errno = 0;
ulval = strtoul(cp, &ep, 8); lval = strtol(cp, &ep, 8);
if (*cp != '\0' && *ep == '\0' && if (*cp != '\0' && *ep == '\0' &&
(errno != ERANGE || ulval != ULONG_MAX)) { !(errno == ERANGE &&
details->umask = (uid_t)ulval; (lval == LONG_MAX || lval == LONG_MIN)) &&
lval <= 0777 && lval >= 0) {
details->umask = (mode_t)lval;
SET(details->flags, CD_SET_UMASK); SET(details->flags, CD_SET_UMASK);
} }
break; break;

View File

@@ -187,6 +187,9 @@ char *fmt_string(const char *var, const char *value);
/* atobool.c */ /* atobool.c */
bool atobool(const char *str); bool atobool(const char *str);
/* atoid.c */
id_t atoid(const char *str, const char **errstr);
/* parse_args.c */ /* parse_args.c */
int parse_args(int argc, char **argv, int *nargc, char ***nargv, int parse_args(int argc, char **argv, int *nargc, char ***nargv,
char ***settingsp, char ***env_addp); char ***settingsp, char ***env_addp);