[Bug 1863894] Re: /etc/bash.bashrc invokes groups command which is slow in large environments
Sam Morris
sam at robots.org.uk
Thu Feb 20 01:32:34 UTC 2020
** Description changed:
/etc/bash.bashrc runs groups(1) whenever a new shell is started.
This command calls getgrgid(3) on every group of which the user is a
member.
In an environment where FreeIPA is used to allow users to log into their
computers using their Active Directory accounts, I have seen each call
to getgrid(3) take over ten seconds. My Active Directory user is a
member of 30 groups and it is not uncommon for users to be a member of
50 or more groups. This results in enormous delays when logging in to a
system with SSH, launching a terminal emulator or even creating a new
tab in an existing terminal emulator.
The code from /etc/bash.bashrc wants to find out whether the user is a
member of the 'sudo' or 'admin' groups in order to display a hint to the
user.
# sudo hint
if [ ! -e "$HOME/.sudo_as_admin_successful" ] && [ ! -e "$HOME/.hushlogin" ] ; then
- case " $(groups) " in *\ admin\ *|*\ sudo\ *)
- if [ -x /usr/bin/sudo ]; then
- cat <<-EOF
- To run a command as administrator (user "root"), use "sudo <command>".
- See "man sudo_root" for details.
-
- EOF
- fi
- esac
+ case " $(groups) " in *\ admin\ *|*\ sudo\ *)
+ if [ -x /usr/bin/sudo ]; then
+ cat <<-EOF
+ To run a command as administrator (user "root"), use "sudo <command>".
+ See "man sudo_root" for details.
+
+ EOF
+ fi
+ esac
fi
This can be rewritten to avoid calling getgrgid(3) for every group that
the user is a member of by doing something like this (untested):
# sudo hint
if [[ -x /usr/bin/sudo ]]; then
- if [[ ! -e $HOME/.sudo_as_admin_successful && ! -e $HOME/.hushlogin ]]; then
- sudo_gid=$(getent group sudo | cut -d: -f3)
- admin_gid=$(getent group admin | cut -d: -f3)
- for gid in $(id -G); do
- if [[ $gid -eq $sudo_gid || $gid -eq $admin_gid ]]; then
- cat <<-EOF
- To run a command as administrator (user "root"), use "sudo <command>".
- See "man sudo_root" for details.
- EOF
- break
- fi
- done
- fi
+ if [[ ! -e $HOME/.sudo_as_admin_successful && ! -e $HOME/.hushlogin ]]; then
+ sudo_gid=$(getent group sudo | cut -d: -f3)
+ admin_gid=$(getent group admin | cut -d: -f3)
+ for gid in $(id -G); do
+ if [[ $gid -eq $sudo_gid || $gid -eq $admin_gid ]]; then
+ cat <<-EOF
+ To run a command as administrator (user "root"), use "sudo <command>".
+ See "man sudo_root" for details.
+ EOF
+ break
+ fi
+ done
+ fi
fi
As an aside: the reason that getgrid(3) is so slow is because it must
fetch the members of each group. There is no quick way to do this in
Active Directory: a recursive search for group members must be
performed, followed by a lookups to retrieve each of their their POSIX
UIDs, and then more lookup to retrieve their POSIX username.
Even when the 'ignore_group_members' sssd(8) option is enabled, which
causes getgrid(3) to report that a group has no members, calling
getgrid(3) on 30-40 groups still takes a few seconds. And this option is
not the default.
It's also not uncommon to have groups with spaces in their names, which
causes groups(1) to produce ambiguous output.
For these reasons it is best to avoid the use of groups(1) in scripts
where more performant and robust alternatives are available.
--
You received this bug notification because you are a member of Ubuntu
Foundations Bugs, which is subscribed to bash in Ubuntu.
https://bugs.launchpad.net/bugs/1863894
Title:
/etc/bash.bashrc invokes groups command which is slow in large
environments
Status in bash package in Ubuntu:
New
Bug description:
/etc/bash.bashrc runs groups(1) whenever a new shell is started.
This command calls getgrgid(3) on every group of which the user is a
member.
In an environment where FreeIPA is used to allow users to log into
their computers using their Active Directory accounts, I have seen
each call to getgrid(3) take over ten seconds. My Active Directory
user is a member of 30 groups and it is not uncommon for users to be a
member of 50 or more groups. This results in enormous delays when
logging in to a system with SSH, launching a terminal emulator or even
creating a new tab in an existing terminal emulator.
The code from /etc/bash.bashrc wants to find out whether the user is a
member of the 'sudo' or 'admin' groups in order to display a hint to
the user.
# sudo hint
if [ ! -e "$HOME/.sudo_as_admin_successful" ] && [ ! -e "$HOME/.hushlogin" ] ; then
case " $(groups) " in *\ admin\ *|*\ sudo\ *)
if [ -x /usr/bin/sudo ]; then
cat <<-EOF
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
EOF
fi
esac
fi
This can be rewritten to avoid calling getgrgid(3) for every group
that the user is a member of by doing something like this (untested):
# sudo hint
if [[ -x /usr/bin/sudo ]]; then
if [[ ! -e $HOME/.sudo_as_admin_successful && ! -e $HOME/.hushlogin ]]; then
sudo_gid=$(getent group sudo | cut -d: -f3)
admin_gid=$(getent group admin | cut -d: -f3)
for gid in $(id -G); do
if [[ $gid -eq $sudo_gid || $gid -eq $admin_gid ]]; then
cat <<-EOF
To run a command as administrator (user "root"), use "sudo <command>".
See "man sudo_root" for details.
EOF
break
fi
done
fi
fi
As an aside: the reason that getgrid(3) is so slow is because it must
fetch the members of each group. There is no quick way to do this in
Active Directory: a recursive search for group members must be
performed, followed by a lookups to retrieve each of their their POSIX
UIDs, and then more lookup to retrieve their POSIX username.
Even when the 'ignore_group_members' sssd(8) option is enabled, which
causes getgrid(3) to report that a group has no members, calling
getgrid(3) on 30-40 groups still takes a few seconds. And this option
is not the default.
It's also not uncommon to have groups with spaces in their names,
which causes groups(1) to produce ambiguous output.
For these reasons it is best to avoid the use of groups(1) in scripts
where more performant and robust alternatives are available.
To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/bash/+bug/1863894/+subscriptions
More information about the foundations-bugs
mailing list