Activity log for bug #1863894

Date Who What changed Old value New value Message
2020-02-19 12:51:05 Sam Morris bug added bug
2020-02-20 01:32:34 Sam Morris 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. /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.
2020-02-27 16:25:41 Thomas Stewart bug added subscriber Thomas Stewart
2023-01-17 22:42:46 Launchpad Janitor bash (Ubuntu): status New Confirmed