diff --git a/compat/getgrouplist.c b/compat/getgrouplist.c index 8573c3498..6e035be84 100644 --- a/compat/getgrouplist.c +++ b/compat/getgrouplist.c @@ -69,9 +69,10 @@ getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroupsp) aix_setauthdb((char *) name); #endif if ((grset = getgrset(name)) != NULL) { + const char *errstr; for (cp = strtok(grset, ","); cp != NULL; cp = strtok(NULL, ",")) { - gid = atoi(cp); - if (gid != basegid) { + gid = atoid(cp, NULL, NULL, &errstr); + if (errstr == NULL && gid != basegid) { if (ngroups == grpsize) goto done; groups[ngroups++] = gid; diff --git a/plugins/group_file/getgrent.c b/plugins/group_file/getgrent.c index 68e004e49..6fb750f3a 100644 --- a/plugins/group_file/getgrent.c +++ b/plugins/group_file/getgrent.c @@ -64,6 +64,8 @@ struct group *mygetgrent(void); struct group *mygetgrnam(const char *); struct group *mygetgrgid(gid_t); +extern id_t atoid(const char *str, const char *sep, char **endp, const char **errstr); + void mysetgrfile(const char *file) { @@ -101,25 +103,31 @@ mygetgrent(void) static struct group gr; static char grbuf[LINE_MAX], *gr_mem[GRMEM_MAX+1]; size_t len; + id_t id; char *cp, *colon; + const char *errstr; int n; +next_entry: if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL) return NULL; memset(&gr, 0, 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 = atoid(cp, NULL, NULL, &errstr); + if (errstr != NULL) + goto next_entry; + gr.gr_gid = (gid_t)id; len = strlen(colon); if (len > 0 && colon[len - 1] == '\n') colon[len - 1] = '\0'; diff --git a/plugins/sudoers/pwutil.c b/plugins/sudoers/pwutil.c index 48f8fc21d..7d2f3e889 100644 --- a/plugins/sudoers/pwutil.c +++ b/plugins/sudoers/pwutil.c @@ -270,10 +270,17 @@ sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home, struct passwd * sudo_fakepwnam(const char *user, gid_t gid) { + const char *errstr; uid_t uid; + debug_decl(sudo_fakepwnam, SUDO_DEBUG_NSS) - uid = (uid_t) atoi(user + 1); - return sudo_mkpwent(user, uid, gid, NULL, NULL); + uid = (uid_t) atoid(user + 1, NULL, NULL, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG, + "uid %s %s", user, errstr); + debug_return_ptr(NULL); + } + debug_return_ptr(sudo_mkpwent(user, uid, gid, NULL, NULL)); } void @@ -432,6 +439,7 @@ struct group * sudo_fakegrnam(const char *group) { struct cache_item_gr *gritem; + const char *errstr; struct group *gr; struct rbnode *node; size_t len, name_len; @@ -444,9 +452,15 @@ sudo_fakegrnam(const char *group) for (i = 0; i < 2; i++) { gritem = ecalloc(1, len); gr = &gritem->gr; - gr->gr_gid = (gid_t) atoi(group + 1); + gr->gr_gid = (gid_t) atoid(group + 1, NULL, NULL, &errstr); gr->gr_name = (char *)(gritem + 1); memcpy(gr->gr_name, group, name_len + 1); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG, + "gid %s %s", group, errstr); + efree(gritem); + debug_return_ptr(NULL); + } gritem->cache.refcnt = 1; gritem->cache.d.gr = gr; @@ -608,6 +622,7 @@ user_in_group(const struct passwd *pw, const char *group) { struct group_list *grlist; struct group *grp = NULL; + const char *errstr; int i; bool matched = false; debug_decl(user_in_group, SUDO_DEBUG_NSS) @@ -617,16 +632,21 @@ user_in_group(const struct passwd *pw, const char *group) * If it could be a sudo-style group ID check gids first. */ if (group[0] == '#') { - gid_t gid = atoi(group + 1); - if (gid == pw->pw_gid) { - matched = true; - goto done; - } - for (i = 0; i < grlist->ngids; i++) { - if (gid == grlist->gids[i]) { + gid_t gid = (gid_t) atoid(group + 1, NULL, NULL, &errstr); + if (errstr != NULL) { + sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG, + "gid %s %s", group, errstr); + } else { + if (gid == pw->pw_gid) { matched = true; goto done; } + for (i = 0; i < grlist->ngids; i++) { + if (gid == grlist->gids[i]) { + matched = true; + goto done; + } + } } } diff --git a/plugins/sudoers/regress/iolog_path/check_iolog_path.c b/plugins/sudoers/regress/iolog_path/check_iolog_path.c index 12fb81ee7..2b0904473 100644 --- a/plugins/sudoers/regress/iolog_path/check_iolog_path.c +++ b/plugins/sudoers/regress/iolog_path/check_iolog_path.c @@ -102,6 +102,7 @@ main(int argc, char *argv[]) char line[2048]; char *file_in = NULL, *file_out = NULL; char *dir_in = NULL, *dir_out = NULL; + const char *errstr; int state = 0; int errors = 0; int tests = 0; @@ -149,7 +150,9 @@ main(int argc, char *argv[]) user_name = strdup(line); break; case 2: - user_gid = atoi(line); + user_gid = (gid_t)atoid(line, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("group ID %s: %s", line, errstr); break; case 3: if (runas_pw->pw_name != NULL) @@ -157,7 +160,9 @@ main(int argc, char *argv[]) runas_pw->pw_name = strdup(line); break; case 4: - runas_pw->pw_gid = atoi(line); + runas_pw->pw_gid = (gid_t)atoid(line, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("group ID %s: %s", line, errstr); break; case 5: user_shost = strdup(line); diff --git a/plugins/sudoers/sudoers.c b/plugins/sudoers/sudoers.c index 1342d9a66..4c092e48a 100644 --- a/plugins/sudoers/sudoers.c +++ b/plugins/sudoers/sudoers.c @@ -300,11 +300,15 @@ sudoers_policy_main(int argc, char * const argv[], int pwflag, char *env_add[], * Look up the timestamp dir owner if one is specified. */ if (def_timestampowner) { - struct passwd *pw; + struct passwd *pw = NULL; - if (*def_timestampowner == '#') - pw = sudo_getpwuid(atoi(def_timestampowner + 1)); - else + if (*def_timestampowner == '#') { + const char *errstr; + uid_t uid = atoid(def_timestampowner + 1, NULL, NULL, &errstr); + if (errstr == NULL) + pw = sudo_getpwuid(uid); + } + if (pw == NULL) pw = sudo_getpwnam(def_timestampowner); if (pw != NULL) { timestamp_uid = pw->pw_uid; @@ -834,17 +838,24 @@ set_fqdn(void) static void set_runaspw(const char *user) { + struct passwd *pw = NULL; debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN) - if (runas_pw != NULL) - sudo_pw_delref(runas_pw); if (*user == '#') { - if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) - runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); - } else { - if ((runas_pw = sudo_getpwnam(user)) == NULL) + const char *errstr; + uid_t uid = atoid(user + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((pw = sudo_getpwuid(uid)) == NULL) + pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); + } + } + if (pw == NULL) { + if ((pw = sudo_getpwnam(user)) == NULL) log_fatal(NO_MAIL|MSG_ONLY, N_("unknown user: %s"), user); } + if (runas_pw != NULL) + sudo_pw_delref(runas_pw); + runas_pw = pw; debug_return; } @@ -855,17 +866,24 @@ set_runaspw(const char *user) static void set_runasgr(const char *group) { + struct group *gr = NULL; debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN) - if (runas_gr != NULL) - sudo_gr_delref(runas_gr); if (*group == '#') { - if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) - runas_gr = sudo_fakegrnam(group); - } else { - if ((runas_gr = sudo_getgrnam(group)) == NULL) + const char *errstr; + gid_t gid = atoid(group + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((gr = sudo_getgrgid(gid)) == NULL) + gr = sudo_fakegrnam(group); + } + } + if (gr == NULL) { + if ((gr = sudo_getgrnam(group)) == NULL) log_fatal(NO_MAIL|MSG_ONLY, N_("unknown group: %s"), group); } + if (runas_gr != NULL) + sudo_gr_delref(runas_gr); + runas_gr = gr; debug_return; } diff --git a/plugins/sudoers/testsudoers.c b/plugins/sudoers/testsudoers.c index c83659b28..936c4c27c 100644 --- a/plugins/sudoers/testsudoers.c +++ b/plugins/sudoers/testsudoers.c @@ -127,6 +127,7 @@ main(int argc, char *argv[]) struct userspec *us; char *p, *grfile, *pwfile; char hbuf[HOST_NAME_MAX + 1]; + const char *errstr; int match, host_match, runas_match, cmnd_match; int ch, dflag, exitcode = 0; debug_decl(main, SUDO_DEBUG_MAIN) @@ -158,7 +159,9 @@ main(int argc, char *argv[]) user_host = optarg; break; case 'G': - sudoers_gid = (gid_t)atoi(optarg); + sudoers_gid = (gid_t)atoid(optarg, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("group ID %s: %s", optarg, errstr); break; case 'g': runas_group = optarg; @@ -173,7 +176,9 @@ main(int argc, char *argv[]) trace_print = testsudoers_print; break; case 'U': - sudoers_uid = (uid_t)atoi(optarg); + sudoers_uid = (uid_t)atoid(optarg, NULL, NULL, &errstr); + if (errstr != NULL) + fatalx("user ID %s: %s", optarg, errstr); break; case 'u': runas_user = optarg; @@ -349,36 +354,48 @@ done: static void set_runaspw(const char *user) { - debug_decl(main, SUDO_DEBUG_UTIL) + struct passwd *pw = NULL; + debug_decl(set_runaspw, SUDO_DEBUG_UTIL) - if (runas_pw != NULL) - sudo_pw_delref(runas_pw); if (*user == '#') { - if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) - runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); - } else { - if ((runas_pw = sudo_getpwnam(user)) == NULL) + const char *errstr; + uid_t uid = atoid(user + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((pw = sudo_getpwuid(uid)) == NULL) + pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); + } + } + if (pw == NULL) { + if ((pw = sudo_getpwnam(user)) == NULL) fatalx(U_("unknown user: %s"), user); } - + if (runas_pw != NULL) + sudo_pw_delref(runas_pw); + runas_pw = pw; debug_return; } static void set_runasgr(const char *group) { - debug_decl(main, SUDO_DEBUG_UTIL) + struct group *gr = NULL; + debug_decl(set_runasgr, SUDO_DEBUG_UTIL) - if (runas_gr != NULL) - sudo_gr_delref(runas_gr); if (*group == '#') { - if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) - runas_gr = sudo_fakegrnam(group); - } else { - if ((runas_gr = sudo_getgrnam(group)) == NULL) + const char *errstr; + gid_t gid = atoid(group + 1, NULL, NULL, &errstr); + if (errstr == NULL) { + if ((gr = sudo_getgrgid(gid)) == NULL) + gr = sudo_fakegrnam(group); + } + } + if (gr == NULL) { + if ((gr = sudo_getgrnam(group)) == NULL) fatalx(U_("unknown group: %s"), group); } - + if (runas_gr != NULL) + sudo_gr_delref(runas_gr); + runas_gr = gr; debug_return; }