ee9e506af2
Previously, the allocation was optimized for an outdated deployment style (that of /etc/group alongside nss_db). The issue here is that this results in extremely poor performance when using SSSD, Winbind or nss_ldap. There were actually two serious bugs here that have been addressed: 1) Running getgrent() loops won't work in most SSSD or Winbind environments, as full group enumeration is disabled by default. This could easily result in auto-allocating a group that was already in use. (This might result in a security issue as well, if the shared GID is a privileged group). 2) For system groups, the loop was always iterating through the complete SYS_GID_MIN->SYS_GID_MAX range. On SSSD and Winbind, this means hundreds of round-trips to LDAP (unless the GIDs were specifically configured to be ignored by the SSSD or winbindd). To a user with a slow connection to their LDAP server, this would appear as if groupadd -r was hung. (Though it would eventually complete). This patch changes the algorithm to be more favorable for LDAP environments, at the expense of some performance when using nss_db. Given that the DB is a local service, this should have a negligible effect from a user's perspective. With the new algorithm, we simply first iterate through all entries in the local database with gr_next(), recording the IDs that are in use. We then start from the highest presumed-available entry and call getgrgid() to see if it is available. We continue this until we come to the first unused GID. We then select that and return it. If we make it through all the remaining IDs without finding a free one, we start over from the beginning of the range and try to find room in one of the gaps in the range. The patch was originally written by Stephen Gallagher and applied identically also to the user allocation by Tomáš Mráz. Signed-off-by: Serge Hallyn <serge@hallyn.com> |
||
---|---|---|
.. | ||
.indent.pro | ||
addgrps.c | ||
age.c | ||
audit_help.c | ||
basename.c | ||
chkname.c | ||
chkname.h | ||
chowndir.c | ||
chowntty.c | ||
cleanup_group.c | ||
cleanup_user.c | ||
cleanup.c | ||
console.c | ||
copydir.c | ||
entry.c | ||
env.c | ||
failure.c | ||
failure.h | ||
find_new_gid.c | ||
find_new_sub_gids.c | ||
find_new_sub_uids.c | ||
find_new_uid.c | ||
getdate.h | ||
getdate.y | ||
getgr_nam_gid.c | ||
getrange.c | ||
hushed.c | ||
idmapping.c | ||
idmapping.h | ||
isexpired.c | ||
limits.c | ||
list.c | ||
log.c | ||
loginprompt.c | ||
mail.c | ||
Makefile.am | ||
motd.c | ||
myname.c | ||
obscure.c | ||
pam_pass_non_interractive.c | ||
pam_pass.c | ||
pwd2spwd.c | ||
pwd_init.c | ||
pwdcheck.c | ||
remove_tree.c | ||
rlogin.c | ||
root_flag.c | ||
salt.c | ||
setugid.c | ||
setupenv.c | ||
shell.c | ||
strtoday.c | ||
sub.c | ||
sulog.c | ||
ttytype.c | ||
tz.c | ||
ulimit.c | ||
user_busy.c | ||
utmp.c | ||
valid.c | ||
xgetgrgid.c | ||
xgetgrnam.c | ||
xgetpwnam.c | ||
xgetpwuid.c | ||
xgetspnam.c | ||
xgetXXbyYY.c | ||
xmalloc.c | ||
yesno.c |