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);
#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;

View File

@@ -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';

View File

@@ -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;
}
}
}
}

View File

@@ -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);

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.
*/
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;
}

View File

@@ -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;
}