Showing posts with label LDAP. Show all posts
Showing posts with label LDAP. Show all posts

Sunday, July 12, 2015

Объединённая служба каталога (LDAP). Установка и настройка

Что такое служба каталога и что такое LDAP?

Служба каталога (Directory Service)— это программный комплекс для хранения и каталогизации информации. По своей сути это очень похоже на обычную базу данных, но с “уклоном” скорее на чтение данных, нежели на их добавление или модификацию. Обычно служба каталога базируется на клиент-серверной архитектуре. Одна из наиболее известных таких систем— это DNS (Domain Name Service): DNS-сервер производит взаимную “трансляцию” имён машин и их IP-адресов. Другие машины в сети могут обращаться к такому серверу за информацией о соответствии имени и адреса. Однако это очень простой пример каталогизации информации. Объекты в такой базе имеют ограниченное количество атрибутов— таких как имя, адрес и ещё несколько дополнительных параметров. Разумеется, служба каталога какого-нибудь предприятия будет содержать более разнообразные данные и иметь гораздо более сложную структуру.
В общем случае, служба каталога должна предоставлять простой, централизованный доступ к данным, которые могут использоваться различными приложениями. Протокол, по которому могла бы работать такая служба, был разработан в ISO (International Standartization Organization), получил номер X.500 и назывался DAP (Directory Access Protocol). В соответствии с этим протоколом любое приложение может получить доступ к информации в каталоге. Там же была предложена гибкая и легко расширяемая информационная структура которая позволяла хранить в принципе любой тип данных. К сожалению, X.500 имел и ряд ограничений, таких как зависимость от коммуникационного уровня, который не являлся стандартным протоколом TCP и запутанность требований к правилам именования объектов. В результате решение на базе этого протокола становилось очень дорогим при обслуживании.
Позже появился протокол LDAP (Lightweight Directory Access Protocol), который позволил реализовать доступ по TCP/IP и мог легко расширяться. В результате появилось решение, позволяющее организовать службу каталога на предприятии любого масштаба.
Сегодня существует несколько реализаций данного протокола от различных фирм. Наиболее известные из них— это Netscape Directory Service™, Microsoft Active Directory™, Novell Directory Service™. Из некоммерческих реализаций LDAP наибольшее распространение получил проект OpenLDAP. Именно его мы и будем рассматривать в данной главе, хотя большинство понятий и определений применимо и к другим реализациям сервера LDAP.

Основные термины

Для понимания работы службы каталога необходимо усвоить несколько ключевых терминов.
  • Данные каталога хранятся в виде объектов или сущностей (от англ. entry), состоящих из специальных полей называемых атрибутами (attributes). Набор атрибутов, их синтаксис и правила поиска определяются схемой каталога (scheme). Все объекты каталога идентифицируются специальным атрибутом— DN (Distinguished Name).
  • Данные в каталоге можно представить в виде древовидной структуры— DIT (Directory Information Tree). Это очень похоже на структуру, используемую многими файловыми системами. Вершиной такого дерева является корневой объект (Root Entry). DN корневого объекта одновременно является суффиксом каталога.
  • Каждый последующий объект в структуре каталога идентифицируется уникальным значением DN который описывает путь к объекту в каталоге. Если продолжить аналогию с файловой системой то DN любого объекта так же включает DN всех объектов стоящих выше по иерархии. Отличие в данном случае только в том, что DN формируется не слева направо, как путь к файлу, а наоборот— справа налево.
  • DN администратора каталога (Root Distinguished Name)— это специальный объект, описывающий администратора каталога. Этот объект указывается в конфигурации сервера, но может отсутствовать в самом каталоге. К такому объекту не применяются списки доступа (ACL). В некоторых реализациях LDAP такой объект может не иметь суффикса.
  • База поиска (Base Distinguished Name)— объект каталога, начиная с которого производится поиск. Дело в том, что не всегда есть необходимость производить поиск по всему дереву каталога; ограничить область поиска можно указанием в запросе базы поиска. По умолчанию этот параметр соответствует суффиксу.

Объекты и атрибуты

Серверы LDAP могут поставляться с несколькими вариантами бэкенда (backend). Например, OpenLDAP имеет такие варианты, как LDBM— собственный формат хранения данных в текстовых файлах; SHELL— интерфейс к базе данных, использующий команды UNIX; PASSWD— простейшая база, использующая стандартные файлы/etc/passwd и /etc/group; SQL— интерфейс к любой базе данных, использующей SQL.
Для процедур импорта и экспорта данных всеми серверами LDAP поддерживается единый формат обмена данными— LDIF. Вот пример такого файла с описанием двух объектов:
dn: dc=example,dc=com
objectClass: top
objectClass: organization
o: example.com
o: Example Inc.

dn: ou=People,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People
description: Example Inc. workers
description: Stuff area
      
Описание каждого объекта в таком файле начинается с атрибута DN. Специальный атрибут objectClass указывает, к каким классам относится данный объект и, следовательно, какие атрибуты он может иметь. В нашем случае принадлежность к классу top означает, что объект обязательно должен иметь атрибут objectClass, а принадлежность к классу organization предполагает наличие нескольких атрибутов, из которых атрибут o является обязательным.
Второй объект находится на одну ступеньку ниже по иерархии и поэтому в его DN включён DN объекта верхнего уровня. Этот объект относится к классуorganizationalUnit и поэтому имеет обязательный атрибут ou.
Можно заметить что некоторые атрибуты (для которых это применимо) могут иметь несколько значений. В данном примере атрибут description имеет два значения. А вот для атрибута dn допустимо только одно значение.
Классы, характеризующие объекты, и атрибуты, составляющие классы, описываются схемой базы. Её пример приведён ниже.
attributetype ( 2.5.4.10 NAME ( 'o' 'organizationName' )
  SUP name
)
attributetype ( 2.5.4.13 NAME 'description'
  EQUALITY caseIgnoreMatch
  SUBSTR caseIgnoreSubstringsMatch
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{1024}
)
objectclass ( 2.5.6.4 NAME 'organization' SUP top STRUCTURAL
  MUST o
  MAY ( userPassword $ searchGuide $ seeAlso $ businessCategory $
    x121Address $ registeredAddress $ destinationIndicator $
    preferredDeliveryMethod $ telexNumber $ teletexTerminalIdentifier $
    telephoneNumber $ internationaliSDNNumber $
    facsimileTelephoneNumber $ street $ postOfficeBox $ postalCode $
    postalAddress $ physicalDeliveryOfficeName $ st $ l $ description
  )
)
      
В данном фрагменте приводятся описания двух атрибутов и одного класса. Вот что означают эти записи:
  • Атрибут o (его можно также называть organizationName) является расширением атрибута name.
  • Атрибут description— это строка длиной до 1024 байт; при поиске в ней регистр символов не учитывается.
  • Класс organization является расширением класса top и имеет единственный обязательный атрибут o. Кроме того имеется большое количество необязательных атрибутов таких как userPassword, businessAddress, street, postOfficeBox и т.д.
Много полезной информации о схемах можно найти по ссылкам на сайте OpenLDAP.

Установка и настройка

Процесс сборки и установки сервера OpenLDAP не отличается от сборки и установки другого программного обеспечения, поставляемого с исходными кодами. Кроме того, практически во всех современных дистрибутивах Linux он поставляется в виде готового пакета. Поэтому уделим больше внимания настройке.

Настройка сервера

Сервер LDAP состоит из двух серверных процессов slapd и slurpd. Процесс slapd занимается приёмом и обработкой запросов от клиентов; это основной процесс, который непосредственно работает с базой данных. Сервис slurpd используется в тех случаях, когда данные нужно реплицировать на другие сервера— он контролирует изменения в базе и при необходимости пересылает их на подчинённые сервера.
Приведём пример конфигурационного файла:
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/nis.schema
      
В первых строках мы подключаем необходимые схемы; в поставке OpenLDAP их около полутора десятков. Подключите только те, которые будете использовать. В принципе, схемы являются частью конфигурационного файла, но для наглядности они вынесены в отдельные фрагменты.
database ldbm
      
В качестве способа хранения используется собственный формат LDBM. Если предполагается обычная конфигурация сервера, то данный формат предпочтителен.
suffix "dc=example,dc=com"
      
Корнем информационной структуры будет являться объект dc=example,dc=com. В принципе, суффикс для каталога можно взять любой, например, o=Example Inc.,c=RU— это не накладывает абсолютно никаких ограничений на функциональность. Однако последнее время все чаще используется именно первый вид суффикса, который подчёркивает, что информационная структура данного предприятия тесно связана со структурой его домена.
rootdn "cn=admin,dc=altlinux,dc=ru"
rootpw secret
      
DN, описывающий администратора и его пароль. В данном случае пароль записан в открытом виде, поэтому файл конфигурации сервера должен иметь соответствующие права доступа, ограничивающие его чтение обычными пользователями. Пароль можно записать и в виде хэша DES или MD5— тогда строка будет иметь следующий вид:
rootpw {MD5}IFJFxyGN3Hap7xsJFBmeTA==
index objectClass eq
      
Формат ldbm поддерживает простейшие индексы с целью ускорения операций поиска. Желательно создать такие индексы по тем атрибутам, по которым предполагается наибольшее количество запросов.
access to attr=userPassword
  by self write
  by anonymous auth
  by * none

access to * by * read
      
Не всегда данные каталога находятся в публичном доступе. Для управления доступам могут использоваться списки доступа (access lists). В данном примере приводятся два списка— в первом из них ограничивается доступ к атрибуту userPassword (полный доступ к нему могут иметь только сам объект либо администратор базы; для всех остальных доступ запрещён). Второе правило гласит, что всем даётся доступ на чтение любых данных (кроме ограниченного предыдущим правилом).
TLSCipherSuite HIGH:MEDIUM:+SSLv2
TLSCertificateFile /etc/openldap/ssl/slapd.pem
TLSCertificateKeyFile /etc/openldap/ssl/slapd.pem
      
LDAP можно использовать для централизованной авторизации пользователей сети вместо NIS+. В таких случаях из каталога может запрашиваться конфиденциальная информация, например, пароль. Для предотвращения перехвата этих данных желательно использовать протокол LDAPS (LDAP via SSL/TLS).
После настройки можно сразу запустить процесс slapd— например, такой командой:
slapd -u ldap -h ldap://127.0.0.1/ ldaps://ldap.altlinux.ru/
или, если вы используете пакет из дистрибутивов ALT Linux
service ldap start
Первый объект, которые нужно создать в базе— это корневой элемент (root entry) который указан в конфигурационном файле как suffix.

Настройка репликации

Одной из важных особенностей LDAP являются встроенные средства репликации данных. Этот механизм реализован в виде отдельного серверного процесса, контролирующего изменения в базе данных и пересылающего эти изменения на другие сервера. Прежде чем включать такую репликацию, необходимо убедиться, что соответствующие данные на обоих серверах идентичны. Это связано с тем, что slurpd пересылает именно изменения на текущем сервере— он не проверяет и не анализирует состояние данных на удалённом сервере. Настройки slurpd находятся в том же файле, что и настройки slapd— поэтому перечислим, что нужно добавить к перечисленным выше параметрам:
replica /var/log/slapd.replog
      
Прежде всего укажем файл, в который slapd будет записывать все свои действия и из которого slurpd будет их читать.
replica host=ldap2.example.com
  tls=yes
  bindmethod=simple
  binddn="cn=slurpd,ou=lug,dc=example,dc=com"
  credentials=secret
      
Для каждого подчинённого сервера описывается такая вот реплика. На подчинённом сервере нужно создать соответствующий объект и указать, что он имеет права на изменение информации. Это делается с помощью соответствующего списка доступа и параметров updatedn и updateref.

Настройка клиента

Существует огромное количество клиентов, работающих с LDAP. Это могут быть почтовые программы, которые обращаются к каталогу в поисках адреса электронной почты сотрудника или за информацией о маршрутизации почты, FTP-сервер, который берет информацию для авторизации своего клиента и многие другие программы— однако все они имеют схожие настройки. Прежде всего это адрес сервера и порт, на котором работает LDAP (обычно это 389 либо 636, если сервер поддерживает протокол LDAPS). Вторым важным параметром является база поиска (Base DN)— в большинстве случаев этот параметр соответствует суффиксу сервера. Третий важный параметр— фильтр поиска. Кроме того, существуют параметры, позволяющие ограничить поиск снизу— например, только самой базой или базой и её под-объектами первого уровня, параметры управляющие поиском в алиасах (alias) и т.п.
Трёх этих параметров в большинстве случаев достаточно, чтобы выполнить запрос к любому серверу LDAP. Однако если на сервере существуют ограничения на доступ к данным, то может потребоваться авторизация. Авторизоваться в LDAP можно, указав DN одного из объектов базы данных LDAP; пароль для такого объекта будет искаться в его атрибуте userPassword.
Ниже приводится фрагмент настройки почтового сервера Postfix:
virtual_maps = ldap:virtual, hash:/etc/postfix/virtual

virtual_server_host = localhost
virtual_search_base = ou=People,dc=example,dc=ru
virtual_query_filter = (&(objectclass=inetLocalMailRecipient)(cn=%s))
virtual_result_attribute = mailLocalAddress,mailRoutingAddress
      
В данном фрагменте описывается, что при определении адреса получателя делается запрос в LDAP с целью найти объект которому это письмо адресовано. Поиск делается по атрибуту cn. Результат берётся из атрибутов mailLocalAddress и mailRoutingAddress. Эти классы и атрибуты описаны схемой misc.

Использование LDAP

LDAP может использоваться в самых различных ситуациях. Здесь мы рассмотрим несколько наиболее распространённых его применений. Поскольку в LDAP хранится полная информация о сотрудниках предприятия, мы можем брать справочную информацию для почтовых программ прямо оттуда. Для начала настроим сервер:
include /etc/openldap/schema/core.schema
include /etc/openldap/schema/cosine.schema
include /etc/openldap/schema/inetorgperson.schema
include /etc/openldap/schema/misc.schema
include /etc/openldap/schema/nis.schema
include /etc/openldap/schema/openldap.schema

pidfile        /var/run/slapd.pid
argsfile       /var/run/slapd.args

directory      /var/lib/ldap/base
database       ldbm
index          objectClass,uid,uidNumber,gidNumber eq
index          cn,name,surName,givenNameeq,subinitial
password-hash  {MD5}

suffix         "dc=example,dc=com"
rootdn         "cn=admin,dc=example,dc=com"
rootpw         {md5}$1$ION4SIII$EYyGEeYt4g2hEe9tjICac.

access to attr=userPassword
  by self write
  by dn=".*,ou=Admins,dc=example,dc=com"
  by anonymous auth
  by * none
access to * by * read

loglevel 512

index objectClass,uid,uidNumber,gidNumber     eq
index cn,mail,surname,givenname               eq,subinitial
      
После этого создадим пользователя ldap, от имени которого будет работать наш сервер и запустим процесс slapd следующей командой:
slapd -u ldap -h 'ldap://127.0.0.1/ ldap//ldap.altlinux.ru/ ldaps://ldap.altlinux.ru'
Теперь можно создать базу данных— например, с помощью утилиты ldapadd:
ldapadd -xWD cn=admin,dc=altlinux,dc=ru -H ldaps://ldap.altlinux.ru -f initial.ldif
Содержимое файла initial.ldif будет такое:
dn: dc=example,dc=com
objectClass: top
objectClass: organization
o: Exapmle Inc.
o: exapmle.com

dn: cn=admin,dc=exapmle,dc=com
objectClass: top
objectClass: organizationalRole
cn: admin
description: Example Inc. LDAP manager

dn: ou=People,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: People
description: Stuff area

dn: uid=obender,ou=People,dc=example,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: Ostap Bender
sn: Bender
givenName: Ostap
uid: obender
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/obender
loginShell: /bin/bash
userPassword: {md5}$1$ION4SIII$EYyGEeYt4g2hEe9tjICac.
mail: obender@example.com
mail: obender@attiresandtoes.com

....

dn: ou=Group,dc=example,dc=com
objectClass: top
objectClass: organizationalUnit
ou: Group
description: Groups of users

dn: cn=luser,ou=Group,dc=example,dc=com
objectClass: top
objectClass: posixGroup
cn: luser
gidNumber: 1000
description: Default group for users presented by LDAP
      
Проверим, что сервер работает сделав к нему анонимный запрос:
$ ldapsearch -xLLL "(uid=obender)"
dn: uid=obender,ou=People,dc=example,dc=com
objectClass: top
objectClass: account
objectClass: posixAccount
objectClass: shadowAccount
objectClass: inetOrgPerson
cn: Ostap Bender
sn: Bender
givenName: Ostap
uid: migor
uidNumber: 1000
gidNumber: 1000
homeDirectory: /home/obender
loginShell: /bin/bash
mail: obender@example.com
mail: obender@attiresandtoes.com
      
Поскольку, согласно нашим настройкам, доступ к атрибуту userPassword имеют только сам пользователь и администратор, то этот атрибут мы не получили. Собственно, он нам и не нужен.

Адресная книга

На сегодняшний день почти все популярные почтовые программы поддерживают возможность использовать LDAP как адресную книгу. В качестве примера возьмём пакет Mozilla; установите пакеты libldap, mozilla, mozilla-mail и запустите программу. Далее:
  • откройте окно настройки (Edit->Preferences...);
  • выберите слева категорию Mail & Newsgroups, подкатегорию Addressing;
  • справа в опциях Address Autocompletion включите Directory Server и нажмите кнопку Edit Directories...;
  • в новом окне нажмите кнопку Add и на вкладке General заполните поля Name: ExampleLDAP, Hostname:ldap.example.com и BaseDN:dc=example,dc=com;
  • при желании на вкладке Advanced можно указать ограничение на количество возвращаемых записей (по умолчанию это 100) и фильтр поиска.
После этого сохраните изменения— и теперь при заполнении поля To: можно писать не адрес, а имя получателя из атрибута cn. Программа произведёт соответствующий поиск и предложит варианты атрибута mail, которые найдёт в базе.
Для настройки другого пакета обратитесь к руководству пользователя вашей программы.

Маршрутизация почты в Postfix.

Предположим, что наше предприятие не имеет своего POP3/IMAP-сервера либо для некоторых сотрудников удобнее получать почту через другой сервер. Для этого нам необходимо принять почту пользователя, приходящую в наш домен, и переправить её на тот адрес который для сотрудника удобнее. Решений для этой задачи существует несколько: в простейшем варианте можно создать в домашнем каталоге пользователя файл .forward, в котором он сам мог бы указать нужный ему адрес. Однако усложним задание— предположим, что на нашем почтовом сервере нет учётной записи для данного пользователя; тогда получается, что этот файл некуда поместить. Второй вариант— настроить пересылку на самом сервере; для этого создается файл /etc/postfix/virtual приблизительного такого вида:
obender@example.com obender@attiresandtoes.com
        
а в конфигурационном файле Postfix указывается
virtual_maps = hash:/etc/postfix/virtual
        
Теперь остаётся только создать хэш и перезапустить Postfix; однако, если мы имеем много таких пользователей и если почтовых серверов существует несколько, то отслеживать синхронное изменение файлов /etc/postfix/virtual становится нелёгкой задачей.
Немного модифицируем наше последнее решение. Перенесём данные из файла /etc/postfix/virtual в LDAP; для этого модифицируем приведённую выше базу следующим образом: добавим пользователю класс inetLocalMailRecipient и новый атрибут mailRoutingAddress.
$ ldapmodify -WD cn=admin,dc=example,dc=com
dn: uid=obender,ou=People,dc=example,dc=com
changetype: modify
objectClass: inetLocalMailRecipient
mailRoutingAddress: obender@attiresandtoes.com
        
После этого изменим настройки Postfix:
virtual_maps = ldap:virtual
virtual_server_host = ldap.example.com
virtual_search_base = ou=People,dc=example,dc=com
virtual_query_filter = (&(mail=%s)(objectClass=inetLocalMailRecipient))
virtual_result_attribute = mailRoutingAddress
        
Теперь почта для данного пользователя будет пересылаться на адрес из атрибута mailRoutingAddress, тем не менее в адресной книге все останется без изменений и там будет показываться “официальный” адрес пользователя из атрибута mail.

Централизованная авторизация.

Разобравшись с почтой, хочется перенести в LDAP и авторизацию. Обычно для этих целей используют NIS+, однако хочется использовать для этого более совершенную технологию— в конце концов, у нас уже есть сервер LDAP, содержащий все необходимые данные по нашим пользователям. Для того, чтобы система искала своих пользователей не только в файле /etc/passwd, необходимо установить пакеты nss_ldap и pam_ldap. Оба пакета имеют общий конфигурационный файл/etc/ldap.conf (в других дистрибутивах это могут быть другие файлы, но синтаксис у них одинаковый).
uri ldaps://ldap.example.com
ldap_version 3
base dc=example,dc=com
timelimit 15
ssl on
        
Подправим файл /etc/nsswitch.conf:
passwd: files ldap
shadow: tcb ldap
group: files ldap
        
Теперь проверяем, подключены ли пользователи из базы:
$ id obender
uid=1000(obender) gid=1000 groups=1000
        
Обратите внимание на то, что сейчас мы обращаемся к серверу по защищённому протоколу LDAPS. Поскольку теперь мы берём из базы крайне важную информацию— пароль пользователя, дополнительная степень защиты будет весьма кстати.

Приложения

RFC
Список RFC, поддерживающих LDAP:
  • RFC 1558: A String Representation of LDAP Search Filters
  • RFC 1777: Lightweight Directory Access Protocol
  • RFC 1778: The String Representation of Standard Attribute Syntaxes
  • RFC 1779: A String Representation of Distinguished Names
  • RFC 1781: Using the OSI Directory to Achieve User Friendly Naming
  • RFC 1798: Connectionless LDAP
  • RFC 1823: The LDAP Application Programming Interface
  • RFC 1959: An LDAP URL Format
  • RFC 1960: A String Representation of LDAP Search Filters
  • RFC 2251: Lightweight Directory Access Protocol (v3)
  • RFC 2307: LDAP as a Network Information Service

Saturday, October 18, 2014

OpenLDAP-SambaPDC-OrgInfo-Posix

Introduction

This article describes how to set up a Windows domain using Samba with OpenLDAP as the primary domain controller that stores Windows account information. This provides a central authentication point for Windows users on the network, thus avoiding the need to manage local user accounts on every Windows PC. It can also allow the use of roaming profiles, where a user can log onto any Windows PC on the network and have the same personal settings in each session.
By using LDAP as the Samba database instead of one of the alternatives, though, much more can be achieved. The LDAP database can also hold other classes of information on each user that can be used for other authentication systems, or for general information as in the case of e-mail contact lists. In this article, the LDAP classes 'person', 'organizationalPerson' and 'inetOrgPerson' store general information about users including e-mail addresses, phone numbers and physical addresses. This information can be utilized by e-mail clients such as Evolution and Thunderbird. The LDAP class 'posixAccount' stores Linux user account information. Similarly to Windows PCs, Linux PCs can be set up to use the OpenLDAP database as a central authentication point. Thus, we have an LDAP server that provides authentication for both Windows and Linux PCs. In addition to this, the LDAP server can potentially be used for controlling access to web systems - please see the very helpful article OpenLDAPServer.
Even if you only want to set up a Samba PDC at this point, you may still want to follow this article. LDAP is a good backend to use. Just skip the posix section.
Once the LDAP database is established, it is good to have a nice GUI or web-based tool to make minor changes and check information in the database. I have checked a few GUIs out and Luma looks good. I refer to this in the article.
Note that to limit the scope of this article, I have removed references to setting up Samba print-serving and file-serving. This is covered in other Samba articles.
Throughout this article, substitute dc=collins with a value appropriate for your organisation - eg. dc=myorganisation,dc=org. Likewise, choose a suitable name for your domain. 

Tested Systems

This has been tested on Hardy Xubuntu 8.04, installing everything from the Ubuntu repositories - ie. samba 3.0.28a, slapd 2.4.9, smbldap-tools 0.9.4-1. Windows XP SP2 was used as the Windows client.
Please add any other versions tested here.
Items Tested:
  • Windows PC could join the domain
  • Windows domain user could log onto the PC
  • Windows domain user could change their password, by pressing Ctrl-Alt-Delete, etc.
  • H: drive appeared and access was correct
  • Roaming profile was automatically created when the domain user logged off at the end of their first session
  • Xubuntu server was set up successfully to use combined LDAP and files as posix authentication mechanism

Initialise OpenLDAP Database

Install OpenLDAP ..
sudo apt-get --yes install slapd ldap-utils db4.2-util
Install Samba documentation containing the Samba schema. Extract samba.schema and copy to the required system area for OpenLDAP.
sudo apt-get --yes install samba-doc
sudo gunzip /usr/share/doc/samba-doc/examples/LDAP/samba.schema.gz
sudo cp -v /usr/share/doc/samba-doc/examples/LDAP/samba.schema /etc/ldap/schema
Decide on an LDAP admin password and generate a SSHA hash key for it.
slappasswd
Create an init.ldif file. Name the 4 OUs Users, Groups, Computers and Idmap for use with smbldap-tools.
dn: dc=collins
objectClass: dcObject
objectClass: organizationalUnit
dc: collins
ou: Collins

dn: cn=admin,dc=collins
objectClass: simpleSecurityObject
objectClass: organizationalRole
cn: admin
description: LDAP administrator
userPassword: {SSHA}...  - insert result from running slappasswd above

dn: ou=Users,dc=collins
objectClass: organizationalUnit
ou: Users

dn: ou=Groups,dc=collins
objectClass: organizationalUnit
ou: Groups

dn: ou=Computers,dc=collins
objectClass: organizationalUnit
ou: Computers

dn: ou=Idmap,dc=collins
objectClass: organizationalUnit
ou: Idmap
Modify /etc/ldap/slapd.conf for this site, add/modify these lines ..
suffix          "dc=collins"
rootdn          "cn=admin,dc=collins"
rootpw {SSHA}...        - insert result from running slappasswd above
Check through all of slapd.conf and replace distinguished name references with cn=admin,dc=collins, etc. Also add a line 'include /etc/ldap/schema/samba.schema' under the other include lines.
# Schema and objectClass definitions
include         /etc/ldap/schema/core.schema
include         /etc/ldap/schema/cosine.schema
include         /etc/ldap/schema/nis.schema
include         /etc/ldap/schema/inetorgperson.schema
include         /etc/ldap/schema/samba.schema
Modify /etc/ldap/ldap.conf - un-comment #BASE and modify ..
BASE "dc=collins"
Initialise OpenLDAP database ..
sudo /etc/init.d/slapd stop
sudo rm -rf /var/lib/ldap/*
sudo slapadd -v -l init.ldif
  /etc/ldap/slapd.conf: line 109: rootdn is always granted unlimited privileges.
  /etc/ldap/slapd.conf: line 126: rootdn is always granted unlimited privileges.
  added: "dc=collins" (00000001)
  added: "cn=admin,dc=collins" (00000002)
  added: "ou=Users,dc=collins" (00000003)
    :  :  :
sudo chown -R openldap:openldap /var/lib/ldap
sudo /etc/init.d/slapd start
Confirm all is OK with a Search ..
ldapsearch -xLLL -b "dc=collins"
  dn: dc=collins
  objectClass: dcObject
  objectClass: organizationalUnit
    :  :  :

Install Luma GUI Admin Tool

Luma is a very nice GUI tool for viewing and editing LDAP entries. See http://luma.sourceforge.net/. It appears that no manual exists for Luma. Maybe because it is so easy to use?
Install and run Luma ..
sudo apt-get --yes install luma
luma &
From the main menu, choose Settings/Edit Server List. Enter localhost as the name for a new server. Click on Authentication in the left pane, and un-tick Anonymous bind, choose Simple as the mechanism, and bind using your LDAP admin account (eg. cn=admin,dc=collins) and enter the LDAP admin password. 
luma-server-settings.png
Now click on the Choose Plugin button and click Browser. Click on the + symbols in the left pane. You should now see something like this ..
luma-save-button2.png
Click on the pen to the right of LDAP Administrator and change the text to LDAP Admin. The Save button is no longer greyed out. If you wish to save this, press the Save button. The Save button will now be greyed out again.

Install and Configure Samba

Install Samba ..
INSTALL="sudo apt-get install"
$INSTALL libtalloc1
$INSTALL smbclient
$INSTALL samba
$INSTALL libpam-smbpass
Create Samba folders that have not been automatically created ..
sudo mkdir -v    /var/lib/samba/profiles
# So that profiles are created when user first logs off ..
sudo chmod 777   /var/lib/samba/profiles
sudo mkdir -v -p /var/lib/samba/netlogon
Edit /etc/samba/smb.conf - so it looks like this .. (Do NOT use valid users = .. or invalid users = root - need to enable root and all machine$ accounts.)
[global]
        # Domain name ..
        workgroup = COLLINS
        # Server name - as seen by Windows PCs ..
        netbios name = LINUXPC
        # Be a PDC ..
        domain logons = Yes
        domain master = Yes
        # Be a WINS server ..
        wins support = true

        obey pam restrictions = Yes
        dns proxy = No
        os level = 35
        log file = /var/log/samba/log.%m
        max log size = 1000
        syslog = 0
        panic action = /usr/share/samba/panic-action %d
        pam password change = Yes

        # Allows users on WinXP PCs to change their password when they press Ctrl-Alt-Del
        unix password sync = no
        ldap passwd sync = yes

        # Printing from PCs will go via CUPS ..
        load printers = yes
        printing = cups
        printcap name = cups

        # Use LDAP for Samba user accounts and groups ..
        passdb backend = ldapsam:ldap://localhost

        # This must match init.ldif ..
        ldap suffix = dc=collins
        # The password for cn=admin MUST be stored in /etc/samba/secrets.tdb
        # This is done by running 'sudo smbpasswd -w'.
        ldap admin dn = cn=admin,dc=collins

        # 4 OUs that Samba uses when creating user accounts, computer accounts, etc.
        # (Because we are using smbldap-tools, call them 'Users', 'Computers', etc.)
        ldap machine suffix = ou=Computers
        ldap user suffix = ou=Users
        ldap group suffix = ou=Groups
        ldap idmap suffix = ou=Idmap
        # Samba and LDAP server are on the same server in this example.
        ldap ssl = no

        # Scripts for Samba to use if it creates users, groups, etc.
        add user script = /usr/sbin/smbldap-useradd -m '%u'
        delete user script = /usr/sbin/smbldap-userdel %u
        add group script = /usr/sbin/smbldap-groupadd -p '%g'
        delete group script = /usr/sbin/smbldap-groupdel '%g'
        add user to group script = /usr/sbin/smbldap-groupmod -m '%u' '%g'
        delete user from group script = /usr/sbin/smbldap-groupmod -x '%u' '%g'
        set primary group script = /usr/sbin/smbldap-usermod -g '%g' '%u'

        # Script that Samba users when a PC joins the domain ..
        # (when changing 'Computer Properties' on the PC)
        add machine script = /usr/sbin/smbldap-useradd -w '%u'

        # Values used when a new user is created ..
        # (Note: '%L' does not work properly with smbldap-tools 0.9.4-1)
        logon drive = H:
        logon home = \\linuxpc\%U
        logon path = \\linuxpc\Profiles\%U
        logon script = logon.bat

        # This is required for Windows XP client ..
        server signing = auto
        server schannel = Auto

[homes]
        comment = Home Directories
        valid users = %S
        read only = No
        browseable = No

[netlogon]
        comment = Network Logon Service
        path = /var/lib/samba/netlogon
        admin users = root
        guest ok = Yes
        browseable = No

[Profiles]
        comment = Roaming Profile Share
        # would probably change this to elsewhere in a production system ..
        path = /var/lib/samba/profiles
        read only = No
        profile acls = Yes
        browsable = No

[printers]
        comment = All Printers
        path = /var/spool/samba
        use client driver = Yes
        create mask = 0600
        guest ok = Yes
        printable = Yes
        browseable = No
        public = yes
        writable = yes
        admin users = root
        write list = root

[print$]
        comment = Printer Drivers Share
        path = /var/lib/samba/printers
        write list = root
        create mask = 0664
        directory mask = 0775
        admin users = root
Write password for the LDAP admin account (eg. cn=admin,dc=collins) into /etc/samba/secrets.tdb - ESSENTIAL!
sudo smbpasswd -W
  Setting stored password for "cn=admin,dc=collins" in secrets.tdb
  New SMB password:
  Retype new SMB password:
Restart Samba ..
sudo /etc/init.d/samba restart
Use the SMB client to check that the Samba server is responding correctly.
smbclient -L linuxpc -U anonymous%
  Anonymous login successful
  Domain=[COLLINS] OS=[Unix] Server=[Samba 3.0.28a]

        Sharename       Type      Comment
        ---------       ----      -------
        print$          Disk      Printer Drivers Share
        share           Disk      General share
        IPC$            IPC       IPC Service (Samba 3.0.28a)
        CLP-300         Printer   Samsung CLP-300
  Anonymous login successful
  Domain=[COLLINS] OS=[Unix] Server=[Samba 3.0.28a]

        Server               Comment
        ---------            -------
        LINUXPC              Samba 3.0.28a

        Workgroup            Master
        ---------            -------
        BERKELEY             FOXGLOVE
        COLLINS              LINUXPC

Populate OpenLDAP Database

As the name implies, smbldap-tools provide the link between Samba and the LDAP database. The tools also put posix and inetOrgPerson entries into the database.
Smbldap-tools provides the following commands ..
  • smbldap-groupadd - add a new group
  • smbldap-groupdel - delete a group
  • smbldap-groupmod - modify a group, including adding or removing members
  • smbldap-groupshow - show the properties of a group, including members
  • smbldap-passwd - change a user password
  • smbldap-populate - populate LDAP database, provide stucture necessary for Samba - see below
  • smbldap-useradd - add a new user account
  • smbldap-userdel - delete a user account
  • smbldap-userlist - list users or machines with some info
  • smbldap-usershow - show information for one user account
  • smbldap-usermod - modify the Unix and Samba properties of a user account (many properties)
  • smbldap-userinfo - modify gecos information in a user account (only a few properties)

Set Up Windows Domain Stucture

Install smbldap-tools and extract the configure.pl script.
sudo apt-get install smbldap-tools
sudo gunzip /usr/share/doc/smbldap-tools/configure.pl.gz
sudo chmod +x /usr/share/doc/smbldap-tools/configure.pl
Before configuring smbldap-tools, check that Samba is running and the Windows domain SID can be retrieved.
ps -e | grep -i "smb"
  4956 ?        00:00:00 smbd
  5096 ?        00:00:00 smbd
sudo net getlocalsid
  SID for domain LINUXPC is: S-1-5-21-2899629268-4176875250-2352135513
You may get an error message from running sudo net getlocalsid such as
[2008/12/23 10:35:05,  0] lib/smbldap_util.c:smbldap_search_domain_info(310)
  smbldap_search_domain_info: Adding domain info for MYDOMAIN failed with NT_STATUS_UNSUCCESSFUL
SID for domain MYDOMAIN is: S-1-5-21-1153465165-1443174390-2997034973
but continue with the installation. You need to finish running and configuring the smbldap-tools in order for the domain info fields to be available.
Now, configure smbldap-tools. The script prompts you to confirm many attribute values that are used when creating new accounts. Simply accept all the values, except with the 2 prompts for passwords, enter the LDAP admin password. You can change any of these values later by editing /etc/smbldap-tools/smbldap.conf.
sudo /usr/share/doc/smbldap-tools/configure.pl
Populate the LDAP database with essential Samba entries. This includes the creation of standard groups, such as Administrators and Domain Users.
sudo smbldap-populate
  Populating LDAP directory for domain COLLINS (S-1-5-21-2899629268-4176875250-2352135513)
  (using builtin directory structure)
  entry dc=collins already exist. 
  entry ou=Users,dc=collins already exist. 
  entry ou=Groups,dc=collins already exist. 
  entry ou=Computers,dc=collins already exist. 
  entry ou=Idmap,dc=collins already exist. 
  adding new entry: uid=root,ou=Users,dc=collins
  adding new entry: uid=nobody,ou=Users,dc=collins
  adding new entry: cn=Domain Admins,ou=Groups,dc=collins
  adding new entry: cn=Domain Users,ou=Groups,dc=collins
  adding new entry: cn=Domain Guests,ou=Groups,dc=collins
  adding new entry: cn=Domain Computers,ou=Groups,dc=collins
  adding new entry: cn=Administrators,ou=Groups,dc=collins
  adding new entry: cn=Account Operators,ou=Groups,dc=collins
  adding new entry: cn=Print Operators,ou=Groups,dc=collins
  adding new entry: cn=Backup Operators,ou=Groups,dc=collins
  adding new entry: cn=Replicators,ou=Groups,dc=collins
  entry sambaDomainName=COLLINS,dc=collins already exist. Updating it...
  Please provide a password for the domain root: 
  Changing UNIX and samba passwords for root
  New password: 
  Retype new password:
Luma will now show the additional information .. luma-populate.png

Index the LDAP Database for Speed

Although, the LDAP system will function without indexes defined in /etc/ldap/slapd.conf, performance will decrease as the number of users increases and warnings will be reported to /var/log/syslog like shown below.
Sep  9 19:34:24 Thich slapd[4929]: <= bdb_equality_candidates: (uidNumber) not indexed 
Sep  9 19:34:24 Thich slapd[4929]: <= bdb_equality_candidates: (uniqueMember) not indexed 
Sep  9 19:34:25 Thich slapd[4929]: <= bdb_equality_candidates: (gidNumber) not indexed 
Sep  9 19:34:25 Thich slapd[4929]: <= bdb_equality_candidates: (memberUid) not indexed 
Sep  9 19:34:25 Thich slapd[4929]: <= bdb_equality_candidates: (uid) not indexed 
Sep  9 17:39:12 Thich slapd[4929]: <= bdb_equality_candidates: (sambaGroupType) not indexed 
Sep  9 17:39:12 Thich slapd[4929]: <= bdb_equality_candidates: (sambaSIDList) not indexed 
Sep  9 17:39:12 Thich slapd[4929]: <= bdb_equality_candidates: (sambaSID) not indexed 
The following index definitions have been copied from /usr/share/doc/smbldap-tools/examples/slapd.conf.gz, but I have removed indexes to attributes that don't exist in my database (eg. nisMapName). This text should be pasted into /etc/ldap/slapd.conf in the database definitions section (ie. after the first database directive).
# Indices to maintain for this database
index objectClass                       eq,pres
index ou,cn,sn,mail,givenname           eq,pres,sub
index uidNumber,gidNumber,memberUid     eq,pres
index loginShell                        eq,pres
# I also added this line to stop warning in syslog ..
index uniqueMember                      eq,pres
## required to support pdb_getsampwnam
index uid                               pres,sub,eq
## required to support pdb_getsambapwrid()
index displayName                       pres,sub,eq
# These attributes don't exist in this database ..
#index nisMapName,nisMapEntry            eq,pres,sub
index sambaSID                          eq
index sambaPrimaryGroupSID              eq
index sambaDomainName                   eq
index default                           sub
Following this, stop the LDAP server, run slapindex, and restart the LDAP server.
sudo /etc/init.d/slapd stop
  Stopping OpenLDAP: slapd.
sudo slapindex 
  WARNING!
  Runnig as root!
  There's a fair chance slapd will fail to start.
  Check file permissions!
  /etc/ldap/slapd.conf: line 128: rootdn is always granted unlimited privileges.
  /etc/ldap/slapd.conf: line 145: rootdn is always granted unlimited privileges.
# Correct the ownership of the index files ..
sudo chown openldap:openldap /var/lib/ldap/*
sudo /etc/init.d/slapd start
  Starting OpenLDAP: slapd

Add Test Account

Create a new user in LDAP. This command creates the classes - person, organizationalPerson, inetOrgPerson, posixAccount, shadowAccount andsambaSamAccount for this user.
sudo smbldap-useradd -a -m -P david
Add root and david to the Windows Administrators group and confirm ..
sudo /usr/sbin/smbldap-groupmod -m 'root' 'Administrators'
sudo /usr/sbin/smbldap-groupmod -m 'david' 'Administrators'
smbldap-groupshow Administrators
You can also see this added information if you refresh the display in Luma, and click on Administrators and david.
IconsPage/note.png
A member of the Administrators group has all administration rights in the domain. You can also give a user or group a limited number of rights in the domain - eg. the right to add a computer to the domain, the right to administer printers. Seehttp://www.samba.org/samba/docs/man/Samba-HOWTO-Collection/rights.html for information on assigning individual rights.
IconsPage/note.png
In a Microsoft environment the Domain Admins group is ordinarily a member of the Administrators group in the domain. With this Samba set up, this is not possible but a similar result is acheived by assigning all rights to Domain Admins with the net rpc rights command - read the How-To mentioned above.

Join Windows XP PC to the Domain

Note that you cannot join Windows XP Home to a domain - this version of XP does not have full Windows networking functionality. You must have a PC running Windows XP Professional.
Log onto the Windows XP PC with an account that has 'Full Access' to the PC - ie. is an Administrator of the PC. Run Control Panel, then the Systemapplet. (If you want to get there quickly, run sysdm.cpl from Start/Run.) Click on the Computer Name tab, then click Change, click Domain, then enter the name of the domain, and click OK. You will then be prompted for a domain account that has access to join a PC to the domain. Any account in Collins\Administrators will suffice. If you have followed the steps above, root or david will do. If you are denied access, re-check the member list of Administrators using Luma.
winxp-joindomain2.png
You will be prompted to reboot the PC. After you have done this the Windows logon dialog box will contain 3 fields - username, password and domain. Choose your domain from the drop down list, and log on as root. Once logged on check that you have an H: drive and explore \\sambaserver\profiles - you should see an empty root folder. This will contain your profile, the next time you logon. Press Ctr-Alt-Del and check that you can change your password.
IconsPage/note.png
When a Windows PC is added to a domain, it adds the global Domain Admins group into the local Administrator group. Therefore, if you add a domain account to Domain Admins it will automatically have administrator access to all Windows PCs that join the domain.

Option: Edit Address Book Information

In Luma, click Choose Plugin and click Address Book. Choose localhost as the server. Click on david in the left pane, and give this entry a full name, title and e-mail address. Then click the Save button.
luma-addressbook.png
Now click Choose Plugin and click Browser. Click david on the left. (You may need to click somewhere else first to refresh the display.) Note how there is a new mail and title attribute.
This information can be used as a contact list within e-mail clients. See the community document Evolution for a brief explanation on how to set up Evolution to use the LDAP database for its Contact list. The article http://kb.wisc.edu/helpdesk/page.php?id=3462 shows how to set up the Thunderbird address book to use LDAP.

Option: LDAP Authentication on Clients

This procedure is only available for computers with Ubuntu 7.10 and later. 
sudo apt-get --yes install ldap-auth-client
  LDAP server Uniform Resource Identifier: ldap://xxxx  - enter the name of the LDAPServer here
  Distinguished name of the search base: dc=collins
  LDAP version to use: 3
  Make local root Database admin: Yes
  Does the LDAP database require login? No
  LDAP account for root: cn=admin,dc=collins
  LDAP root account password: <enter the LDAP admin password>
sudo auth-client-config -a -p lac_ldap
Test - see if the list of groups and users includes those users and groups in LDAP.
getent group
    :   :
  - output will include Windows groups held in LDAP ..
  Domain Admins:*:512:root
  Domain Users:*:513:
  Domain Guests:*:514:
  Domain Computers:*:515:
  Administrators:*:544:root,david
  Account Operators:*:548:
  Print Operators:*:550:
  Backup Operators:*:551:
  Replicators:*:552:
    :   :
getent passwd
  - output will include user accounts that only exist in LDAP (eg. david)
If there is a problem, the first places to look are /var/log/auth.log and /etc/ldap.conf. Also, try stopping apparmor /etc/init.d/apparmor stop. 
IconsPage/important.pngThere is a problem with libnss-ldap where, even for system users listed in /etc/passwd, LDAP is contacted to find out if the user is in any LDAP groups. This can cause the system to come to a virtual stand-still if the LDAP server is unavailable. To get around this problem, there is a directive called nss_initgroups_ignoreusers. List all your local system accounts after this directive. The article http://www.nabble.com/nsswitch.conf-issues-with-LDAP-Auth--td6259466.html suggests the following options in /etc/ldap.conf.
  timelimit 15
  bind_timelimit 15
  bind_policy soft
  nss_initgroups_ignoreusers root,sys,... and all your other local system accounts in /etc/passwd ...
IconsPage/important.pngIf you get an error "Cannot set your user group.." at the Ubuntu login screen, reboot the computer. This should fix the problem.
View /etc/nsswitch.conf to see the combination and order of systems that are being used for authentication. Run man nsswitch.conf for a detailed explanation.
IconsPage/note.png
The LDAP server itself can be set up similarly to use this OpenLDAP database for logon authentication. The URI will be specified as ldap://localhost.
IconsPage/note.png
On laptops or on a home network where the LDAP server is not always running, it may be important to cache credentials on the user's PC so that they can always logon to the PC, even when the LDAP server is not available. This can be done using libpam-ccreds - refer to the Community Document PamCcredsHowto.
IconsPage/note.png
With the basic LDAP connection used in this article, passwords and other LDAP information are sent across the network as clear text. This may not be a problem in a home network or a small one-office business, but beyond that is is good practice to encrypt the LDAP information going over the network - refer to the Community Document SecuringOpenLDAPConnections.

Option: Migrate Linux Accounts into LDAP

This section is included to complete the describing of smbldap-tools. You might not have any existing Linux accounts or groups that you want to migrate into LDAP. You might prefer just to create new users and groups, using smbldap-useradd, etc. If you do want to migrate some posix accounts, though, this is how you can do it using smbldap-tools.
Extract Migration Scripts Supplied by smbldap-tools ..
sudo gunzip /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-accounts.gz
sudo gunzip /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-groups.gz
sudo chmod +x /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-groups
sudo chmod +x /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-accounts 
cp -v /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-groups .
cp -v /usr/share/doc/smbldap-tools/examples/migration_scripts/smbldap-migrate-unix-accounts .
Make copies of /etc/passwd and /etc/group and open the copies in an editor. Remove all system groups (eg. scanner, syslog) and system accounts (eg. mail, uucp), leaving only user logon accounts (eg. david, fred) and groups that are used for managing user logon accounts (eg. engineers, accountants). Only the latter will be transferred into LDAP. Be sure to remove root and nobody - there are already entries for these in the LDAP database.
cp -v /etc/group .
cp -v /etc/passwd .
mousepad passwd &
mousepad group &
Preview the migration of the selected groups (remove -n from the command line when you want it to run for real). Note: Add -a to the command line if you want the groups to also appear in the Samba domain.
sudo ./smbldap-migrate-unix-groups -G group -v -n
Preview the migration of selected user accounts (remove -n from the command line when you want it to run for real). Note: Add -a to the command line if you want the user accounts to appear in the Samba domain.
sudo ./smbldap-migrate-unix-accounts -P passwd -S /etc/shadow -v -n

See also