учебники, программирование, основы, введение в,

 

Утилиты и функции, обслуживающие понятие "пользователь"

Данные, ассоциированные с пользователем
Операционная система, соответствующая стандарту POSIX, должна поддерживать базу данных пользователей, в которой о каждом из них хранится по крайней мере следующая информация:

  • имя пользователя;
  • числовой идентификатор пользователя;
  • числовой идентификатор начальной группы;
  • начальный рабочий каталог;
  • начальная программа пользователя.

Поясним смысл перечисленных элементов данных.
Каждый зарегистрированный пользователь ОС имеет имя, которое он указывает для целей идентификации при входе в систему. После проведения идентификации и, как правило, аутентификации пользователя, с ним ассоциируются (неотрицательные) числовые идентификаторы пользователя и начальной группы. В отличие от имен, ОС оперирует ими во всех случаях, кроме первоначальной идентификации. Затем запускается начальная программа пользователя (например, командный интерпретатор shell) с указанным начальным рабочим каталогом.
Поля начального рабочего каталога и начальной программы пользователя могут быть пустыми; в таком случае их трактовка зависит от реализации. Обычно в системе определена подразумеваемая начальная программа, в качестве которой обычно используется /bin/sh.
Пользователи объединяются в группы; каждый пользователь является членом хотя бы одной из них. Для групп также существует база данных, ее записи содержат по крайней мере следующие поля:

  • имя группы;
  • числовой идентификатор группы;
  • список пользователей, которым разрешено становиться членами данной группы.

В базе данных пользователей указывается идентификатор начальной группы, в нее пользователь попадает сразу после входа в систему. В процессе работы возможен переход в другую группу (см. далее описание утилиты newgrp), однако на эти переходы наложены ограничения в виде списка возможных членов группы.
С объектно-ориентированной точки зрения можно считать, что класс "пользователь" предоставляет один метод - начальную программу. Его можно применить для программирования определенных услуг. Например, если нужно дать возможность любому человеку (не обязательно зарегистрированному пользователю), оказавшемуся рядом со свободным терминалом, узнать текущие дату и время, заводят пользователя date с начальной программой /bin/date.
Опросить ассоциированные с пользователем данные (точнее, идентификаторы и имена пользователя и начальной группы, а также всех групп, членами которых ему разрешено быть, - так называемых дополнительных групп) позволяет служебная программа
id  [имя_пользователя]
Если имя_пользователя опущено, выдается информация о текущем пользователе и его текущей группе.
Пример использования служебной программы id. Команда
id root
может выдать на стандартный вывод следующий результат:
uid=0(root) gid=0(root) groups=0(root),
1(bin),2(daemon),3(sys),4(adm),6(disk),
10(wheel)
Числовой идентификатор 0 характеризует суперпользователя, который в большинстве Unix-систем не подвержен контролю прав доступа.
Входное имя текущего пользователя можно узнать также с помощью утилиты
logname
и функции getlogin():
#include <unistd.h>
char *getlogin (void);
Отметим, что одному идентификатору пользователя может соответствовать несколько записей в базе данных пользователей, различающихся входными именами и, возможно, другими атрибутами; logname и getlogin() выдают имя, под которым начат текущий сеанс работы с ОС.
Над базой данных пользователей определены операции поиска по идентификатору или имени пользователя, реализуемые, соответственно, функциями getpwuid() и getpwnam() :
#include <pwd.h>
struct passwd *getpwuid (uid_t uid);
#include <pwd.h>
struct passwd *getpwnam (const char *name);
Листинг 3.1. Описание функций getpwuid() и getpwnam().
По стандарту структура passwd должна содержать по крайней мере следующие поля, соответствующие описанным выше обязательным элементам базы данных пользователей:
char  *pw_name;  /* Имя пользователя */

uid_t  pw_uid;   /* Числовой идентификатор
пользователя */
gid_t  pw_gid;   /* Числовой идентификатор
начальной группы */
char  *pw_dir;   /* Начальный рабочий
каталог */
char  *pw_shell; /* Начальная программа
пользователя */
Типы uid_t и gid_t определяются в заголовочном файле <sys/types.h>.
Приведем пример выдачи информации о текущем пользователе и пользователе root с идентификатором 0.
Листинг 3.2. Пример работы с базой данных пользователей.
По окончании работы этой программы может быть получен следующий результат:
Листинг 3.3. Возможный результат работы с базой данных пользователей.
Аналогичные функции имеются для поиска в базе данных групп - getgrgid() и getgrnam():
#include <grp.h>
struct group *getgrgid (gid_t gid);
#include <grp.h>
struct group *getgrnam (const char *name);
Листинг 3.4. Описание функций getgrgid() и getgrnam().
Структура group обязана содержать поля
char   *gr_name;/* Имя группы */
gid_t   gr_gid; /* Числовой идентификатор
группы */
char  **gr_mem; /* Указатель на ограниченный
пустым указателем массив
символьных указателей на
имена пользователей,
которым разрешено
становиться членами
данной группы */
Применение функции getgrgid() отражено в.
Листинг 3.5. Пример работы с базой данных групп.
Приведенная в качестве примера программа может привести к результату, показанному в:
Пользователи, включенные в группу
с идентификатором 1:
root     bin      daemon
Листинг 3.6. Возможный результат работы с базой данных групп.
Для смены текущей группы пользователя предназначена служебная программа newgrp (стандарт POSIX-2001 относит ее к числу необязательных, входящих в расширение "Мобильность пользователей", UP):
newgrp  [-l] [группа]
Группа, в которую осуществляется переход, задается именем или числовым идентификатором. Будучи вызванной без аргументов, утилита newgrp возвращает пользователя в его начальную группу, заданную в базе данных пользователей.
При смене группы порождается новый процесс, в рамках которого запускается новый экземпляр командного интерпретатора, наследующий у своего предшественника текущий каталог и значения переменных окружения. При указании опции -l окружение формируется так, будто пользователь заново вошел в систему.
Если пользователь не входит в список возможных членов новой группы, при переходе в нее может запрашиваться пароль, однако в стандарте POSIX-2001 этот аспект считается зависящим от реализации. Более того, отмечается, что в базе данных групп нет удобных способов задания паролей, поэтому их использование в приложениях не приветствуется, а со временем пароли групп могут стать ненужными.

http://localhost:3232/img/empty.gifСлужебные программы, обслуживающие взаимодействие пользователей

Активными мы будем называть пользователей, работающих в системе в некоторый момент времени.
Чтобы узнать, какие пользователи активны и за какими терминалами они работают, можно воспользоваться служебной программой
who
(заметим, что стандарт POSIX-2001 трактует ее как необязательную, входящую в расширение "Мобильность пользователей").
Выдача утилиты who может выглядеть, например, так (правый столбец означает время входа в систему):
galat    ttyS4    Aug 22 12:41
kost     ttyS6    Aug 22 10:09
К той же дополнительной категории, что и who, принадлежат утилиты write, talk и mesg (а также описанная выше служебная программа newgrp).
После установления соединения утилита
write  имя_пользователя [терминал]
позволяет построчно пересылать стандартный ввод отправителя на терминал пользователя-получателя. Аргументы имя_пользователя и терминал задаются в том виде, как их выводит служебная программа who. Необязательный аргумент [терминал] нужен в тех случаях, когда пользователь-получатель вошел в систему с нескольких терминалов.
Утилиту
talk  имя_пользователя [терминал]
можно рассматривать как более современный аналог write, поскольку она имеет экранный интерфейс и поддерживает двустороннее взаимодействие активных пользователей.
С помощью служебной программы
mesg [y|n]
пользователь может разрешить или запретить установление соединений со своим терминалом. При вызове без аргументов mesg выдает текущий статус терминала.
Приведем пример употребления описанных служебных программ. Рассылку сообщения-аргумента всем активным пользователям можно реализовать посредством shell-процедуры .
who | while read a b c
do
write $a $b << !
$1 !
done
Листинг 3.7. Пример использования утилит who и write.
Обратим внимание на использование во вставке значения аргумента shell-процедуры.
Базовым средством обеспечения почтового взаимодействия между пользователями, согласно стандарту POSIX-2001, является служебная программа mailx. Она позволяет и отправлять, и получать письма. В первом случае ее следует вызывать командной строкой
mailx  [-s тема] адрес ...
во втором -
mailx -e
или
mailx  [опция ...]
или
mailx  -f [опция ...] [почтовый_ящик]
В процессе отправки текст письма читается со стандартного ввода. При получении всеми указанными выше способами, кроме последнего, проверяется системный почтовый ящик, выделенный текущему пользователю, а при наличии опции -f в качестве почтового ящика используется явно заданный файл. Опция -e предписывает только проверить почтовый ящик и, если он не пуст, вернуть код успеха.
В режиме получения можно отправлять письма и управлять содержимым почтового ящика (для чего утилита mailx предоставляет весьма богатый набор команд), однако поддержку этого режима стандарт POSIX-2001 относит к числу необязательных возможностей.
При отправке писем shell-процедурами часто пользуются вставками:
address=...
. . .
mailx $address << !
. . .
текст письма
. . .
!
Листинг 3.8. Пример использования вставки для формирования письма.
Разумеется, интерактивные пользователи редко применяют утилиту mailx напрямую; для работы с почтой практически во всех ОС имеются средства с более дружественным интерфейсом.

 

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика