Выбрать главу
7.3. Резюме

С использованием семейства функций malloc процесс может выделять и высвобождать память в куче в динамическом режиме. При рассмотрении реализации этих функций было показано, что в программах, неправильно обращающихся с блоками выделенной памяти, могут происходить различные неприятности. Кроме того, было отмечено, что для содействия обнаружению источника подобных ошибок доступно несколько отладочных средств.

Функция alloca() выделяет память в стеке. Эта память автоматически высвобождается при возвращении из функции, вызвавшей alloca().

7.4. Упражнения

7.1. Измените программу из листинга 7.1 (free_and_sbrk.c) так, чтобы она выводила текущее значение крайней точки программы после каждого выполнения функции malloc(). Запустите программу, указав небольшой размер выделяемого блока. Тем самым будет продемонстрировано, что функция malloc() не использует sbrk() для изменения положения крайней точки программы при каждом вызове, а вместо этого периодически выделяет более крупные фрагменты памяти, из которых возвращает вызывающему коду небольшие фрагменты.

7.2. (Повышенной сложности.) Реализуйте функции malloc() и free().

8. Пользователи и группы

У каждого пользователя имеется уникальное имя для входа в систему и связанный с ним числовой идентификатор пользователя (UID). Пользователи могут состоять в одной или нескольких группах. У каждой группы также есть уникальное имя и идентификатор группы (GID).

Основное предназначение пользовательских и групповых идентификаторов — определение принадлежности различных системных ресурсов и управление правами, предоставляемыми процессам по доступу к этим ресурсам. Например, каждый файл принадлежит конкретному пользователю и группе, а у каждого процесса есть несколько пользовательских и групповых идентификаторов, определяющих владельцев процесса и набор прав для доступа к файлу (подробности изложены в главе 9).

В этой главе мы рассмотрим системные файлы, используемые для определения пользователей и групп в системе, а затем библиотечные функции для извлечения информации из этих файлов. В завершение мы разберем работу функции crypt(), используемой для шифрования и аутентификации паролей входа в систему.

8.1. Файл паролей: /etc/passwd

В системном файле паролей, /etc/passwd, содержится по одной строке для каждой имеющейся в системе учетной записи пользователя. Каждая строка состоит из семи полей, отделенных друг от друга двоеточиями (:):

mtk: x:1000:100:Michael Kerrisk:/home/mtk:/bin/bash

Рассмотрим эти поля по порядку следования.

• Имя для входа в систему. Это уникальное имя, которое пользователь должен вводить при входе в систему. Зачастую его также называют именем пользователя. Имя для входа в систему можно рассматривать как легко читаемый (символьный) идентификатор, соответствующий числовому идентификатору пользователя (который вскоре будет рассмотрен). Это имя (вместо числового UID) выводят на экран при запросе принадлежности файла такие программы, как ls(1), например при вводе команды ls — l.

Зашифрованный пароль. В этом поле содержится 13-символьный зашифрованный пароль (более подробно мы рассмотрим его в разделе 8.5). Если в поле пароля содержится любая другая строка, в частности строка с другим количеством символов, значит, вход с этой учетной записью недопустим, поскольку такая строка не может представлять действующий зашифрованный пароль. При этом следует учесть, что, если включен режим теневых паролей (что обычно и бывает), данное поле игнорируется. В этом случае поле пароля в /etc/passwd содержит букву x (хотя на ее месте может быть любая непустая символьная строка), а зашифрованный пароль хранится в теневом файле (см. раздел 8.2). Если поле пароля в /etc/passwd пустое, значит, для регистрации под этой учетной записью пароль не нужен (это правило действует даже при наличии теневых паролей).

Здесь будет считаться, что пароли зашифрованы с помощью исторически сложившейся и по-прежнему широко используемой в UNIX схемы шифрования паролей под названием Data Encryption Standard (DES). Схему DES можно заменить другими схемами, например MD5, которая создает из данных на входе 128-битный профиль сообщения (разновидность хеша). В файле паролей (или теневом файле паролей) это значение сохраняется в виде 34-символьной строки.