2
0
mirror of https://github.com/sudo-project/sudo.git synced 2025-08-31 14:25:15 +00:00

Cache the user's group IDs and group names separately and only

resolve group IDs -> names when needed.  If the sudoers file doesn't
contain groups we will no longer try to resolve all the user's group
IDs to names, which can be expensive on some systems.
This commit is contained in:
Todd C. Miller
2016-08-13 16:27:44 -06:00
parent c3b8e97a6e
commit 985ab1dd3e
8 changed files with 408 additions and 190 deletions

View File

@@ -492,11 +492,11 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
gid_t egid;
size_t glsize;
char *cp, *gid_list;
struct group_list *grlist = sudo_get_grlist(runas_pw);
struct gid_list *gidlist = sudo_get_gidlist(runas_pw);
/* We reserve an extra spot in the list for the effective gid. */
glsize = sizeof("runas_groups=") - 1 +
((grlist->ngids + 1) * (MAX_UID_T_LEN + 1));
((gidlist->ngids + 1) * (MAX_UID_T_LEN + 1));
gid_list = malloc(glsize);
if (gid_list == NULL)
goto oom;
@@ -513,10 +513,10 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
goto bad;
}
cp += len;
for (i = 0; i < grlist->ngids; i++) {
if (grlist->gids[i] != egid) {
for (i = 0; i < gidlist->ngids; i++) {
if (gidlist->gids[i] != egid) {
len = snprintf(cp, glsize - (cp - gid_list), ",%u",
(unsigned int) grlist->gids[i]);
(unsigned int) gidlist->gids[i]);
if (len < 0 || (size_t)len >= glsize - (cp - gid_list)) {
sudo_warnx(U_("internal error, %s overflow"), __func__);
free(gid_list);
@@ -526,7 +526,7 @@ sudoers_policy_exec_setup(char *argv[], char *envp[], mode_t cmnd_umask,
}
}
command_info[info_len++] = gid_list;
sudo_grlist_delref(grlist);
sudo_gidlist_delref(gidlist);
}
if (def_closefrom >= 0) {
if (asprintf(&command_info[info_len++], "closefrom=%d", def_closefrom) == -1)
@@ -678,9 +678,9 @@ sudoers_policy_close(int exit_status, int error_code)
sudo_gr_delref(runas_gr);
runas_gr = NULL;
}
if (user_group_list != NULL) {
sudo_grlist_delref(user_group_list);
user_group_list = NULL;
if (user_gid_list != NULL) {
sudo_gidlist_delref(user_gid_list);
user_gid_list = NULL;
}
free(user_gids);
user_gids = NULL;