Когда вы запускаете groups username , он ищет 1 данного пользователя в /etc/passwd и /etc/group (хотя это может быть LDAP, NIS или что-то еще 2) и показывает все найденные группы.
С другой стороны, когда вы запускаете команду groups без каких-либо аргументов, она просто перечисляет все группы, которым она сама принадлежит 3, что не обязательно совпадает с тем, что указано в /etc/group . (См. Ниже для объяснения.) На самом деле, единственный поиск в /etc/group предназначен для перевода GID в имена групп.
Каждый процесс имеет набор учетных данных, который содержит (среди прочего) "реальный идентификатор группы" (первичный GID), "эффективный идентификатор группы" (EGID) и список идентификаторов "дополнительной группы" (вторичные GID). По умолчанию процесс наследует свои учетные данные от своего родителя; однако процессам, выполняющимся от имени пользователя root (UID 0) или имеющим возможность CAP_SETUID , разрешено устанавливать произвольные учетные данные.
В частности, когда вы входите в Linux (будь то в tty, X11 или через SSH), процесс входа в систему (/bin/login, gdm, sshd) ищет ваше имя пользователя, чтобы определить ваш UID, основной GID и вторичные GID. , На персональном компьютере это просто означает чтение соответствующих строк из файлов passwd и group (или NIS, LDAP и т.д.).
Затем процесс входа в систему переключается с 4 на эти учетные данные перед началом сеанса, и каждый процесс, который вы запускаете с этого момента, будет иметь одинаковые идентификаторы UID и GID - система больше не проверяет /etc/group 5 и не принимает никаких изменений. сделал.
Таким образом, процесс /usr/bin/groups будет принадлежать тем же группам, что и вы, когда вы вошли в систему, а не тому, о чем говорит база данных.
Примечание. Приведенное выше объяснение также применимо практически ко всем Unix; к семейству Windows NT (за исключением того, что UID и GID все называются "SID", нет "основной группы", учетные данные называются "токеном процесса", а CAP_SETUID - SeCreateTokenPrivilege или SeTcbPrivilege); и, вероятно, для большинства других многопользовательских операционных систем.
1 getpwuid() и getgrouplist() используются для поиска групп пользователей.
2 В Linux glibc использует /etc/nsswitch.conf чтобы определить, где искать эту информацию.
3 groups используют getgid(), getegid() и getgroups() для получения собственных учетных данных.
4 setuid(), setgid(), initgroups() и связанные с ними.
5 Исключением, конечно же, являются различные инструменты, работающие с повышенными правами (setuid), такие как su , sudo , sg , newgrp , pkexec и так далее. Это означает, что su $USER создаст оболочку с обновленным списком групп.