Use atoid() not atoi() when parsing uids/gids.

This commit is contained in:
Todd C. Miller
2013-12-05 15:51:56 -07:00
parent 2508da6f68
commit e1ac1a2ff3
6 changed files with 121 additions and 52 deletions

View File

@@ -69,9 +69,10 @@ getgrouplist(const char *name, gid_t basegid, gid_t *groups, int *ngroupsp)
aix_setauthdb((char *) name); aix_setauthdb((char *) name);
#endif #endif
if ((grset = getgrset(name)) != NULL) { if ((grset = getgrset(name)) != NULL) {
const char *errstr;
for (cp = strtok(grset, ","); cp != NULL; cp = strtok(NULL, ",")) { for (cp = strtok(grset, ","); cp != NULL; cp = strtok(NULL, ",")) {
gid = atoi(cp); gid = atoid(cp, NULL, NULL, &errstr);
if (gid != basegid) { if (errstr == NULL && gid != basegid) {
if (ngroups == grpsize) if (ngroups == grpsize)
goto done; goto done;
groups[ngroups++] = gid; groups[ngroups++] = gid;

View File

@@ -64,6 +64,8 @@ struct group *mygetgrent(void);
struct group *mygetgrnam(const char *); struct group *mygetgrnam(const char *);
struct group *mygetgrgid(gid_t); struct group *mygetgrgid(gid_t);
extern id_t atoid(const char *str, const char *sep, char **endp, const char **errstr);
void void
mysetgrfile(const char *file) mysetgrfile(const char *file)
{ {
@@ -101,25 +103,31 @@ mygetgrent(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;
id_t id;
char *cp, *colon; char *cp, *colon;
const char *errstr;
int n; int n;
next_entry:
if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL) if ((colon = fgets(grbuf, sizeof(grbuf), grf)) == NULL)
return NULL; return NULL;
memset(&gr, 0, sizeof(gr)); memset(&gr, 0, sizeof(gr));
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
return NULL; goto next_entry;
*colon++ = '\0'; *colon++ = '\0';
gr.gr_name = cp; gr.gr_name = cp;
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
return NULL; goto next_entry;
*colon++ = '\0'; *colon++ = '\0';
gr.gr_passwd = cp; gr.gr_passwd = cp;
if ((colon = strchr(cp = colon, ':')) == NULL) if ((colon = strchr(cp = colon, ':')) == NULL)
return NULL; goto next_entry;
*colon++ = '\0'; *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); len = strlen(colon);
if (len > 0 && colon[len - 1] == '\n') if (len > 0 && colon[len - 1] == '\n')
colon[len - 1] = '\0'; colon[len - 1] = '\0';

View File

@@ -270,10 +270,17 @@ sudo_mkpwent(const char *user, uid_t uid, gid_t gid, const char *home,
struct passwd * struct passwd *
sudo_fakepwnam(const char *user, gid_t gid) sudo_fakepwnam(const char *user, gid_t gid)
{ {
const char *errstr;
uid_t uid; uid_t uid;
debug_decl(sudo_fakepwnam, SUDO_DEBUG_NSS)
uid = (uid_t) atoi(user + 1); uid = (uid_t) atoid(user + 1, NULL, NULL, &errstr);
return sudo_mkpwent(user, uid, gid, NULL, NULL); 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 void
@@ -432,6 +439,7 @@ struct group *
sudo_fakegrnam(const char *group) sudo_fakegrnam(const char *group)
{ {
struct cache_item_gr *gritem; struct cache_item_gr *gritem;
const char *errstr;
struct group *gr; struct group *gr;
struct rbnode *node; struct rbnode *node;
size_t len, name_len; size_t len, name_len;
@@ -444,9 +452,15 @@ sudo_fakegrnam(const char *group)
for (i = 0; i < 2; i++) { for (i = 0; i < 2; i++) {
gritem = ecalloc(1, len); gritem = ecalloc(1, len);
gr = &gritem->gr; 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); gr->gr_name = (char *)(gritem + 1);
memcpy(gr->gr_name, group, name_len + 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.refcnt = 1;
gritem->cache.d.gr = gr; 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_list *grlist;
struct group *grp = NULL; struct group *grp = NULL;
const char *errstr;
int i; int i;
bool matched = false; bool matched = false;
debug_decl(user_in_group, SUDO_DEBUG_NSS) 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 it could be a sudo-style group ID check gids first.
*/ */
if (group[0] == '#') { if (group[0] == '#') {
gid_t gid = atoi(group + 1); gid_t gid = (gid_t) atoid(group + 1, NULL, NULL, &errstr);
if (gid == pw->pw_gid) { if (errstr != NULL) {
matched = true; sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_DIAG,
goto done; "gid %s %s", group, errstr);
} } else {
for (i = 0; i < grlist->ngids; i++) { if (gid == pw->pw_gid) {
if (gid == grlist->gids[i]) {
matched = true; matched = true;
goto done; goto done;
} }
for (i = 0; i < grlist->ngids; i++) {
if (gid == grlist->gids[i]) {
matched = true;
goto done;
}
}
} }
} }

View File

@@ -102,6 +102,7 @@ main(int argc, char *argv[])
char line[2048]; char line[2048];
char *file_in = NULL, *file_out = NULL; char *file_in = NULL, *file_out = NULL;
char *dir_in = NULL, *dir_out = NULL; char *dir_in = NULL, *dir_out = NULL;
const char *errstr;
int state = 0; int state = 0;
int errors = 0; int errors = 0;
int tests = 0; int tests = 0;
@@ -149,7 +150,9 @@ main(int argc, char *argv[])
user_name = strdup(line); user_name = strdup(line);
break; break;
case 2: 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; break;
case 3: case 3:
if (runas_pw->pw_name != NULL) if (runas_pw->pw_name != NULL)
@@ -157,7 +160,9 @@ main(int argc, char *argv[])
runas_pw->pw_name = strdup(line); runas_pw->pw_name = strdup(line);
break; break;
case 4: 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; break;
case 5: case 5:
user_shost = strdup(line); user_shost = strdup(line);

View File

@@ -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. * Look up the timestamp dir owner if one is specified.
*/ */
if (def_timestampowner) { if (def_timestampowner) {
struct passwd *pw; struct passwd *pw = NULL;
if (*def_timestampowner == '#') if (*def_timestampowner == '#') {
pw = sudo_getpwuid(atoi(def_timestampowner + 1)); const char *errstr;
else 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); pw = sudo_getpwnam(def_timestampowner);
if (pw != NULL) { if (pw != NULL) {
timestamp_uid = pw->pw_uid; timestamp_uid = pw->pw_uid;
@@ -834,17 +838,24 @@ set_fqdn(void)
static void static void
set_runaspw(const char *user) set_runaspw(const char *user)
{ {
struct passwd *pw = NULL;
debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN) debug_decl(set_runaspw, SUDO_DEBUG_PLUGIN)
if (runas_pw != NULL)
sudo_pw_delref(runas_pw);
if (*user == '#') { if (*user == '#') {
if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) const char *errstr;
runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); uid_t uid = atoid(user + 1, NULL, NULL, &errstr);
} else { if (errstr == NULL) {
if ((runas_pw = sudo_getpwnam(user)) == 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); 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; debug_return;
} }
@@ -855,17 +866,24 @@ set_runaspw(const char *user)
static void static void
set_runasgr(const char *group) set_runasgr(const char *group)
{ {
struct group *gr = NULL;
debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN) debug_decl(set_runasgr, SUDO_DEBUG_PLUGIN)
if (runas_gr != NULL)
sudo_gr_delref(runas_gr);
if (*group == '#') { if (*group == '#') {
if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) const char *errstr;
runas_gr = sudo_fakegrnam(group); gid_t gid = atoid(group + 1, NULL, NULL, &errstr);
} else { if (errstr == NULL) {
if ((runas_gr = sudo_getgrnam(group)) == 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); 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; debug_return;
} }

View File

@@ -127,6 +127,7 @@ main(int argc, char *argv[])
struct userspec *us; struct userspec *us;
char *p, *grfile, *pwfile; char *p, *grfile, *pwfile;
char hbuf[HOST_NAME_MAX + 1]; char hbuf[HOST_NAME_MAX + 1];
const char *errstr;
int match, host_match, runas_match, cmnd_match; int match, host_match, runas_match, cmnd_match;
int ch, dflag, exitcode = 0; int ch, dflag, exitcode = 0;
debug_decl(main, SUDO_DEBUG_MAIN) debug_decl(main, SUDO_DEBUG_MAIN)
@@ -158,7 +159,9 @@ main(int argc, char *argv[])
user_host = optarg; user_host = optarg;
break; break;
case 'G': 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; break;
case 'g': case 'g':
runas_group = optarg; runas_group = optarg;
@@ -173,7 +176,9 @@ main(int argc, char *argv[])
trace_print = testsudoers_print; trace_print = testsudoers_print;
break; break;
case 'U': 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; break;
case 'u': case 'u':
runas_user = optarg; runas_user = optarg;
@@ -349,36 +354,48 @@ done:
static void static void
set_runaspw(const char *user) 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 (*user == '#') {
if ((runas_pw = sudo_getpwuid(atoi(user + 1))) == NULL) const char *errstr;
runas_pw = sudo_fakepwnam(user, runas_gr ? runas_gr->gr_gid : 0); uid_t uid = atoid(user + 1, NULL, NULL, &errstr);
} else { if (errstr == NULL) {
if ((runas_pw = sudo_getpwnam(user)) == 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); fatalx(U_("unknown user: %s"), user);
} }
if (runas_pw != NULL)
sudo_pw_delref(runas_pw);
runas_pw = pw;
debug_return; debug_return;
} }
static void static void
set_runasgr(const char *group) 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 (*group == '#') {
if ((runas_gr = sudo_getgrgid(atoi(group + 1))) == NULL) const char *errstr;
runas_gr = sudo_fakegrnam(group); gid_t gid = atoid(group + 1, NULL, NULL, &errstr);
} else { if (errstr == NULL) {
if ((runas_gr = sudo_getgrnam(group)) == 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); fatalx(U_("unknown group: %s"), group);
} }
if (runas_gr != NULL)
sudo_gr_delref(runas_gr);
runas_gr = gr;
debug_return; debug_return;
} }