В предыдущей части статьи мы благополучно разобрались с общесистемными настройками авторизации аккаунтов из сервера каталогов . Теперь поговорим о том, как создавать новые группы UNIX в СК и добавлять учётные записи пользователей в составе этих групп. Уточню на всякий случай, что в данном случае, речь идёт не о групповых политиках или о чём-то подобном, а об обычных UNIX-группах, традиционно представленных как односложная плоская структура /etc/group. В LDAP на степень сложности этой структуры ограничений не накладывается, поэтому она может быть представлена более логичным образом – например, в виде дерева.
Разделяемые библиотеки – модули подсистем NSS и PAM, – о которых шла речь в предыдущей части статьи, обычно (если это не переопределено параметрами, указанными в конфигурационном файле /etc/ldap.conf) осуществляют поиск UNIX-группы в СК по objectClass=posixGroup и наличию атрибутов gid и gidNumber. Отличительное имя базы поиска и глубина поиска, как мы уже знаем, задаются параметром nss_base_group в файле /etc/ldap.conf. Таким образом, создание группы в СК технически выглядит как создание объекта класса posixGroup в любой ветке, попадающей в заданную область поиска. Давайте, например, добавим группу FreeUsers в ветку ou=Groups,ou=home,o=Moscow,c=RU. Для этого сформируем узел базы поиска ou=Groups:
dn: ou=Groups,ou=home,o=Moscow,c=RU objectClass: organizationalUnit ou: Groups decsription: UNIX groups here
А затем прикрепим к этому узлу первую группу:
dn: cn=FreeUsers,ou=Groups,ou=home,o=Moscow,c=RU objectClass: posixGroup gidNumber: 1000 cn: FreeUsers description: Free peoples for whom we write our free software
Для того, чтобы система могла «увидеть» добавляемые нами объекты, прежде всего необходимо настроить права доступа к соответствующим записям в СК. Ранее мы уже говорили о том, что доступ на запись ко всем атрибутам объектов, описывающим системные аккаунты и группы UNIX, должны иметь процессы с эффективным пользовательским идентификатором администратора системы. Для того, чтобы эти процессы могли получить соответствующие привилегии на доступ в СК, в файле /etc/ldap.conf указывается соответствующий DN – значение параметра rootbinddn, а пароль для авторизации берётся из файла /etc/ldap.secret
ПРИМЕЧАНИЕ: В файле /etc/ldap.secret не должно быть никаких, в то числе и служебных (перевод строки, ESC-последовательности, которые могут быть вставлены некоторыми устаревшими или неправильно настроенными текстовыми редакторами после нажатия клавиш, не относящихся к алфавитно-цифровому блоку) других символов, кроме собственно пароля. Для того, чтобы гарантированно не ошибиться, а заодно правильно установить маску доступа к файлу, ограничив доступ на чтение пользователю root, автор рекомендует записывать пароль командой
echo -n 'ПАРОЛЬ' > /etc/ldap.secret chmod 600 /etc/ldap.secret
Поскольку в ldap.secret открытым текстом записан пароль для dn, имеющего право на запись в СК, на этот файл устанавливаетмя маска доступа «rw- — —», восьмеричный код 600.
С программами, запускаемыми с EUID=0 (т.е. с правами администратора системы), всё понятно, но как быть с непривилегированными процессами, запрашивающими доступ к виртуальным базам passwd и group? Эти процессы подключаются к СК анонимно,поэтому для того, чтобы учётные записи пользователей в каталоге могли хотя бы по минимуму читать атрибуты необходимые для работы – например, соответствия между uid и uidNumber, gid и gidNumber (в переводе на русский язык: между числовым и символьными идентификаторами пользователя и группы соответственно), – Вам необходимо разрешить чтение при анонимном доступе к соотв. ветвям каталога. Разумеется, из числа атрибутов, доступных на чтение, должны быть исключены пароли пользователей.
Далее нам предстоит создать новую учётную запись пользователя и добавить её в группу FreeUsers. Но здесь перед нами встаёт дилемма: в какую ветвь следует поместить новый объект СК? С одной стороны, все пользователи должны бы размещаться в отдельной ветке, как это часто рекомендуется в специальной литературе, поскольку традиционно структура базы passwd в UNIX – совершенно плоская, а принадлежность пользователей тем или иным группам является скорее средством контроля доступа, нежели логической организации и упорядочения системы, так что из двух учётных записей с одинаковыми именами, но принадлежащим разным группам, будет работать только одна, даже если у них разные значения uidNumber. Но с другой стороны – СК это всё-таки средство, позволяющее идеально отразить иерархический характер отношений и отношений принадлежности, а с этой точки зрения было бы правильным размещать пользователей, принадлежащих группе, в самостоятельной ветке ниже узла-контейнера данной группы. Впрочем, я своего мнения ни в коем разе не навязываю – ваша рука всему владыка, и то, как будет в итоге выглядеть Каталог, решать только вам.
Стандартным объектным классом для хранения авторизационной информации учётной записи пользователя UNIX является posixAccount, описанный в файле nis.schema стандартной поставки OpenLDAP и присутствующий во всех cn=schema,cn=config серверов каталогов, ведущих свою родословную от Netscape iPlanet (Fedora DS, Sun Java System (ONE) DS, OpenDS). Также в учётной записи пользователя должен присуствовать objectClass=shadowAccount, привносящий крайне мало дополнительной информации (например, дополняющий свойства объекта полем срока действия пароля), но необходимый для совместимости с некоторыми приложениями и службами UNIX, которые обращаются за авторизационными данными, минуя NSS, напрямую в сервер каталогов. К числу таких служб, например, относится сервер удалённого входа OpenSSH с патчем поддержки LDAP (подробнее о его настройке читайте в одном из следующих выпусков). В обобщённом виде LDIF-дамп учётной записи пользователя должен выглядеть следующим образом:
dn: uid=ACCOUNT_NAME,BASE_DN objectClass: top objectClass: posixAccount objectClass: shadowAccount uid: ACCOUNT_NAME cn: FULL_NAME uidNumber: UID_NUMBER gidNumber: GID_NUMBER homeDirectory: $HOME loginShell: $SHELL userPassword: PASSWORD gecos: SOME_INFO description: SOME_MORE_INFO
Назначение указанных полей приведено в след. таблице:
Поле | Описание |
ACCOUNT_NAME | Имя пользователя в том виде, в каком оно будет видно системе. Именно в атрибуте uid следует указывать имя пользователя (логин в систему) |
FULL_NAME | Полное имя пользователя. Отображается некоторыми менеджерами входа в систему. На самом деле чаще всего в реальных случаях ACCOUNT_NAME = FULL_NAME |
UID_NUMBER | Численный идентификатор пользователя как субъекта системы, наделённого теми или иными полномочиями (правами доступа). Традиционно разрешения на доступ к объектам системы соотносятся именно с численным идентификатором, а не с именем пользователя, которое служит е более, чем hash-ключом для поиска UID_NUMBER. |
GID_NUMBER | Численный идентификатор группы. Именно к основной группе, на принадлежность к которой указывает данное поле, относится вторая битовая триада в восьмеричной маске прав доступа пользователя. (Например, r-x в одной из самых распространённых масок: rwxr-x—) |
$HOME | Домашний каталог пользователя. Как известно, именно сюда пользователь попадает после регистрации в системе (авторизации). |
$SHELL | Оболочка пользователя. Программа, на которую передаётся управление после авторизации пользователя. |
PASSWORD | Пароль. В LDAP может храниться как в шифрованном виде, так и открытым текстом. Понятно, что последнее нежелательно. |
SOME_INFO | Это так называемое поле GECOS, в котором содержится информация о пользователе в произвольной подаче. Ограничение – только на длину поля (не более N символов). |
SOME_MORE_INFO | Прочая информация о пользователе. Или прогноз погоды на 10 лет вперёд |
В класс объектов posixAccount включен исчерпывающий набор атрибутов, достаточный для того, чтобы описать UNIX-аккаунт, но их явно недостаточно для описания собственно объекта – того человека, который под настоящим аккаунтом авторизуется. Например, у реального человека конечно же есть номер телефона и e-mail-адрес – основные контакты, по которым его можно будет найти, например для того, чтобы сообщить о блокировании его учётной записи. Также неплохо было бы знать владельца аккаунта в лицо для того, чтобы успеть вовремя разминуться с ним при случае.Возможность хранить все эти сведения, а также большое количество другой полезной информации о пользователе вместе с его UNIX-аккаунтом, предоставляет стек объектных классов, на вершине которого находится objectClass=inetOrgPerson, а именно:
objectClass: top objectClass: person pbjectClass: organizationalPerson objectClass: inetOrgPerson objectClass: posixAccount objectClass: shadowAccount
В данном случае речь идёт, – ни больше ни меньше, – о простой и безболезненной интеграции виртуальных баз passwd-groups-shadow с адресной книгой. Мы ещё не раз будем приводить полезные примеры подобных объединений свойств различных классов объектов – иногда это будет получаться простым и очевидным образом, как это имеет место быть в описанном случае с дополнением стека posixAccount, иногда – понадобится знание устройства схем LDAP – в любом случае для администратора, который до этого имел дело лишь с традиционными базами данных, это будет похоже на магию: LDAP даёт возможность делать многое из того, что и не снилось СУБД, в качестве отличной альтернативы табличным хранилищам данных предлагая фантастически гибкий объектно-ориентированный подход.
Между прочим, небольшую фотографию-аватар, из атрибута jpegPhoto некоторые дистрибутивы (например, SuSE) уже наловчились использовать для визуального представления пользователей на графическом экране входа в систему