newgrp
, мы узнали о том, что группам в Unix
можно назначать пароли, о том, что эта команда позволяет
пользователю менять свою (основную) группу. Мы выяснили, что эта
команда появилась в Unix V6, что гораздо раньше, чем я ожидал. Меня
тогда заинтересовал вопрос о том, как именно работала команда
newgrp
в Unix V7. Исходный код V7 (а так же справку и
другие материалы) можно найти на tuhs.org. Поэтому
ничто не мешает нам почитать код реализации этой команды,
находящийся в файле
newgrp.c.(Можно посмотреть и исходный код, имеющий отношение к V6, но он гораздо сложнее, поэтому я буду рассматривать код V7. Помимо того, что V7 обычно считают системой, с которой началась современная Unix, всё, что было сделано до V7, выглядит иначе, и, как минимум, кажется немного странным.)
Я полагал, что
newgrp
работает с группами, защищёнными
паролями, примерно так: кто угодно может выполнить команду
наподобие newgrp GROUP
, и если ему известен пароль, он
будет помещён в группу без необходимости указания его в качестве
(потенциального) члена группы в /etc/group
. Возможно,
именно так работает современная версия newgrp
,
доступная в вашем дистрибутиве. Но в V7 эта команда работала иначе.
Начнём с извлечения из справки (newgrp.1):Пароль требуется в том случае, если у группы есть пароль, а у пользователя нет.
Когда большинство пользователей входит в систему, они являются членами группы other. Команда newgrp известна командной оболочке, которая выполняет её напрямую, без форка.
Во-первых, если только вы не являетесь членом специальной группы
other
, вы должны быть записаны в
/etc/group
независимо от того, назначен ли группе
пароль или нет. Затем, как сказано в справке, пароль группы
требуется лишь в том случае, если у вашей учётной записи пароля
нет. Если же у учётной записи есть пароль, то пароль группы
игнорируется. Другими словами, можно не использовать пароль группы
для того чтобы иметь возможность предоставить кому угодно, знающему
такой пароль, потенциальную возможность доступа к группе. Пароль
группы используется только для защиты группы от входа в неё
пользователей с аккаунтами без паролей (если такие пользователи в
системе присутствуют и если они внесены в дополнительную
группу).При работе с группами, которым назначен пароль, обычная Linux-версия
newgrp
ведёт себя с такими группами,
членом которых вы являетесь, так же, как и V7-версия команды. Но
она ещё и позволяет входить в любые группы, для которых задан
пароль, в том случае, если этот пароль вам известен (так сказано в
справке, я это не проверял). Во FreeBSD, к которой у меня есть
доступ, пользоваться паролями групп
не рекомендуется, в справке говорится, что newgrp
обычно устанавливается без бита setuid
. Ещё там
сказано, что пароль запрашивается только тогда, когда пользователь
не входит в число членов группы.(Я полагаю, что это значит, что в стандартной установке FreeBSD пользователь не может использовать
newgrp
для перехода
в группу, в которую он был добавлен через
/etc/group
.)Возможно, вас заинтересовало последнее предложение из процитированной мной справки по V7-версии
newgrp
.
Причина наличия этой особенности заключается в том, чтобы исключить
существование дополнительных процессов командной оболочки, которые,
вероятно, пользователю не нужны (это привело бы к использованию
дополнительных системных ресурсов на маломощных машинах, на которых
работала V7). С концептуальной точки зрения, если выполняют команду
newgrp
, то обычно стремятся к тому, чтобы переключить
текущую сессию командной оболочки на новую группу. Если оболочка
просто выполнит newgrp
как обычную команду, то будет
осуществлено переключение групп для её собственного процесса, а
затем будет выполнена программа /bin/sh
, дающая
пользователю новую оболочку в новой группе. Это было бы похоже на
то, как если бы пользователь выполнил бы команду sh
в
login-оболочке. Если при таком подходе выполнить несколько команд
newgrp
, то всё закончится тем, что у пользователя
будет целая куча оболочек.А командная оболочка V7 распознаёт команду
newgrp
(а
так же команду login
) и не создаёт форк для её
выполнения. Вместо этого она запускает newgrp
,
пользуясь системным вызовом exec
, и заменяет
login-оболочку на newgrp
(которая затем идеально
заменяет её другой оболочкой, и V7-версия newgrp
, на
самом деле, всегда стремится к тому, чтобы открывать таким образом
новую командную оболочку).(Тут всё самое интересное кроется в комбинации msg.c и xec.c; взгляните на обработку
SYSLOGIN
).Исследуете ли вы старые дистрибутивы Unix для того чтобы лучше понять современные системы?