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.
caches as needed on demand. Also remove calls to sudo_freepwcache()
and sudo_freegrcache() that are immediately followed by execve(),
they are not needed.
Sudo never iterates over the passwd or group file.
Rename sudo_set{pw,gr}ent() -> sudo_mk{pw,gr}cache() and
use sudo_free{pw,gr}cache() instead of sudo_end{pw,gr}ent().
This fixes a bug where we could dereference a NULL pointer when we
look up a negative cached entry which is stored as a NULL passwd
or group struct pointer. Bug #743.
This should not be possible in practice and we can safely return
the new (potentially duplicate) item as it will be freed by the
caller. Make sudo_set_grlist() return an error on failure instead
of calling fatalx().
then calls gettext().
Add U_ macro that calls warning_gettext() instead of gettext().
Rename warning2()/error2() back to warning_nodebug()/error_nodebug().
MAXHOSTNAMELEN and the MIN/MAX macros. We now use PATH_MAX and
HOST_NAME_MAX throughout without falling back on MAXPATHLEN or
MAXHOSTNAMELEN and define our own MIN/MAX macros as needed.
increase the total length, free the old buffer and allocate a new
one. This is less error prone and saves us from having to adjust
all the pointers in the buffer. This code path is only taken when
there are groups longer than the length of the user field in struct
utmp or utmpx, which should be quite rare.
The sudo front-end will now use getgrouplist() to get the user's
list of groups if getgroups() fails or returns zero groups so we
always have a list of the user's groups. For systems with
mbr_check_membership() which support more that NGROUPS_MAX groups
(Mac OS X), skip the call to getgroups() and use getgrouplist() so
we get all the groups.
group_info and use it to store both, along with a count for each.
Cache group info on a per-user basis using getgrouplist() to get
the groups. We no longer need special to special case the user or
list user for user_in_group() and thus no longer need to reset the
groups list when listing another user.
result of getgroups()) to names and store both the group names and
ids in the sudo_user struct. When matching groups in the sudoers
file, match based on the names in the groups list first and
only do a gid-based match when we absolutely have to. By matching
on the group name (as it is listed in sudoers) instead of id
(which we would have to resolve) we save a lot of group lookups
for sudoers files with a lot of groups in them.