Консультация № 175941
09.01.2010, 00:31
0.00 руб.
0 7 1
Уважаемые эксперты!

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

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

Имеем следующее.
Настроенный керберос, выдающий билеты (и mount.cifs, монтирующий ресурсы сервера по ntlm).

Проблемы следующие.
Winbind, естественно, без включения машины в домен не работает.
Ldapsearch -х сервер не находит (думаю, что и так ясно, что при таких делах после включения на стандартный вывод стала выдаваться следующая информация: "nscd: nss_ldap: could not search LDAP server - Server is unavailable").

Какая может быть запись dn при вызове ldapsearch с ключем -D вместо несрабатывающей стандартной uid=user-login,ou=Users,dc=domain, или, хотя бы, при помощи какой программы можно было бы это узнать (с учётом существующих вин.машин с работающим ЛДАПом, подрубленных к этому серверу)?
Можно ли ещё как решить эту задачу, не прибегая к написанию собственного pam модуля (к программированию я не имею никакого отношения)?
В противном случае не могли бы вы привести содержание исходника такого простейшего модуля и пошаговую инструкцию по его компиляции?

Заранее благодарю.
Андрей.

Обсуждение

Неизвестный
09.01.2010, 12:03
общий
это ответ
Здравствуйте, CAEman.

Без написания собственного, ну не обязательно pam-модуля, но скрипта или чего-то подобного, не обойтись. Потому что задача весьма специфична и отнюдь не тривиальна - почему нельзя включать в домен, например? Фактически она распадается на две задачи - как проверить наличие переданного пользователя в домене и как создать для него домашний каталог.

Задача первая. Решается (по крайней мере для Windows 2003) ТОЛЬКО при наличии любой учетной записи домена с известным паролем, необходимой для подключения к домену, поскольку в Windows 2003 по умолчанию отключен так называемый anonymous bind, то есть возможность подключения к LDAP без имени и пароля. Если какой-либо учетной записи нет, проверить наличие логина не удастся. Если же такая учетная запись есть (у нее может не быть никаких прав - самое главное - она должна быть!), то достаточно получить атрибут sAMAccountName. При этом подключаться рекомендую не к конкретному uid,а непосредственно к корню. Кроме того, для Windows 2003 (и выше наверное, не проверял) ОБЯЗАТЕЛЬНО поставить в ldap.conf параметр "REFERRALS off". Пример запуска ldpasearch в приложении. ldap_binddn - это как раз имя пользователя, существующего в домене, а SHELTON.NET - это собственно имя домена, 192.168.50.1 - адрес dc

Задача вторая. Решается как раз pam-модулем. Насчет создания профиля по умолчанию ничего не скажу, потому что использовал данный модуль только для создания домашнего каталога, достаточного для работы в консоли, но не думаю, что там есть что-то сложное - KDE например, сам все создаст. Взять такой модуль можно здесь - http://openoffice.mirahost.ru/fileZ/software/pam_mkhome.tar.bz2. Автор этого модуля, к сожалению не дал никаких инструкций о том, как его собирать и как настраивать, ладно хоть ман написал. Модуль был доработан мной, поскольку изначально автор предполагал, что он будет запускаться в секции session, но это как раз неправильно и действия по созданию домашнего каталога должны выполняться в секции account.

Можно также вместо ldapsearch попробовать использовать модуль pam_ldap (http://www.padl.com/download). Данный модуль как раз выполнит задачу по аутентификации (прописывается в секцию auth), а модуль pam_mkhomе - по управлению учетной записью (секция account). Поскольку оба действия являются необходимыми, оба модуля должны быть с атрибутами required.



Приложение:
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin
ldap_basedn="dc=shelton,dc=net"
ldap_binddn=ldapread@SHELTON.NET
ldap_common_filter="(&(sAMAccountName=*)(sAMAccountType=805306368))"
# Do LDAP search and keep results
ldapsearch -D $ldap_binddn -w qwerty{123} -LLL -h 192.168.50.1 \
-b $ldap_basedn -P 3 -a always $ldap_common_filter sAMAccountName
Неизвестный
09.01.2010, 12:04
общий
Задача явно не на один вопрос, если будут вопросы (а они обязательно будут) - пишите в форум
Неизвестный
15.01.2010, 14:13
общий
Спасибо за ответ.

Насчёт скрипта мне на одном форуме написали:
"
Думаю, что такой скрипт на shell написать нельзя, поскольку в
результате должна получиться загружаемая библиотека с
соответствующим API. Но, написание таких модулей, к примеру на
Python, кажется, возможно.
"
Это неправда?
Задача и состоит в том, чтобы ничего на сервере не менять и администраторской учётной записи вообще не использовать.
Насчёт ldapsearch.
На вин.машине, входящей в домен, пользователей которого нужно авторизовать на лин.машине, nltest /dsgetdc:domain выдаёт:
"
DC: \\server.domain
Address: \\xxx.xxx.x.xxx
Dom Guid: c6d56383-2f9d-4236-9644-628653063863
Dom Name: domain
Forest Name: domain
Dc Site Name: Default-First-Site-Name
Our Site Name: Default-First-Site-Name
Flags: PDC GC DS LDAP KDC TIMESERV GTIMESERV WRITABLE DNS_DC DNS_DOMAIN DNS_FOREST CLOSE_SITE
The command completed successfully
"
Я пробовал менять в предложенном Вами скрипте и на server.domain, и просто на domain, и с параметром "REFERRALS off" в ldap.conf (не знаю, что он означает), и без, используя учётную запись, при помощи которой ldp.exe на упомянутой машине прекрасно осуществляет bind (правда, если введён правильный пароль) c результатом:
"
res = ldap_bind_s(ld, NULL, &NtAuthIdentity, 1158); // v.3
{NtAuthIdentity: User='user'; Pwd= <unavailable>; domain = 'domain'.}
Authenticated as dn:'user'.
"
Результат же запуска скрипта один:
"
SASL/GSSAPI authentication started
ldap_sasl_interactive_bind_s: Local error (-2)
"
В значении параметра ldap_common_filter ничего не нужно было менять?
Может, нужно было ещё и запрос пароля включить?
И почему, вообще, идёт SASL (я, конечно, могу и ошибаться, но, кажется, если используется не безопасное соединение, а по 389 порту, то такой ошибки появляться не должно)?
А следующий вывод на подрубленной к домену виндовой машине ldap.exe при выполнении bind никак не может здесь подсказать, что ещё нужно изменить в скрипте:
"
ld = ldap_open("", 389);
Established connection to .
Retrieving base DSA information...
Result <0>: (null)
Matched DNs:
Getting 1 entries:
>> Dn:
1> currentTime: 12/25/2009 18:24:41 ;
1> subschemaSubentry: CN=Aggregate,CN=Schema,CN=Configuration,DC=domain;
1> dsServiceName: CN=NTDS Settings,CN=SERVER,CN=Servers,CN=Default-First-Site-Name,CN= Sites,CN=Configuration,DC=domain;
5> namingContexts: DC=domain; CN=Configuration,DC=domain; CN=Schema,CN=Configuration,DC=domain; DC=DomainDnsZones,DC=domain; DC=ForestDnsZones,DC=domain;
1> defaultNamingContext: DC=domain;
1> schemaNamingContext: CN=Schema,CN=Configuration,DC=domain;
1> configurationNamingContext: CN=Configuration,DC=domain;
1> rootDomainNamingContext: DC=domain;
23> supportedControl: 1.2.840.113556.1.4.319; 1.2.840.113556.1.4.801; 1.2.840.113556.1.4.473; 1.2.840.113556.1.4.528; 1.2.840.113556.1.4.417; 1.2.840.113556.1.4.619; 1.2.840.113556.1.4.841; 1.2.840.113556.1.4.529; 1.2.840.113556.1.4.805; 1.2.840.113556.1.4.521; 1.2.840.113556.1.4.970; 1.2.840.113556.1.4.1338; 1.2.840.113556.1.4.474; 1.2.840.113556.1.4.1339; 1.2.840.113556.1.4.1340; 1.2.840.113556.1.4.1413; 2.16.840.1.113730.3.4.9; 2.16.840.1.113730.3.4.10; 1.2.840.113556.1.4.1504; 1.2.840.113556.1.4.1852; 1.2.840.113556.1.4.802; 1.2.840.113556.1.4.1907; 1.2.840.113556.1.4.1948;
2> supportedLDAPVersion: 3; 2;
12> supportedLDAPPolicies: MaxPoolThreads; MaxDatagramRecv; MaxReceiveBuffer; InitRecvTimeout; MaxConnections; MaxConnIdleTime; MaxPageSize; MaxQueryDuration; MaxTempTableSize; MaxResultSetSize; MaxNotificationPerConn; MaxValRange;
1> highestCommittedUSN: 44295516;
4> supportedSASLMechanisms: GSSAPI; GSS-SPNEGO; EXTERNAL; DIGEST-MD5;
1> dnsHostName: server.domain;
1> ldapServiceName: domain:server$@DOMAIN;
1> serverName: CN=SERVER,CN=Servers,CN=Default-First-Site-Name,CN=Sites,CN= Configuration,DC=domain;
3> supportedCapabilities: 1.2.840.113556.1.4.800; 1.2.840.113556.1.4.1670; 1.2.840.113556.1.4.1791;
1> isSynchronized: TRUE;
1> isGlobalCatalogReady: TRUE;
1> domainFunctionality: 0;
1> forestFunctionality: 0;
1> domainControllerFunctionality: 2;
-----------
res = ldap_bind_s(ld, NULL, &NtAuthIdentity, 1158); // v.3
{NtAuthIdentity: User='user'; Pwd= <unavailable>; domain = domain.}
Authenticated as dn:'user'.
"
Тот же результат и при анонимном подсоединении, только вместо "user" выдаёт "NULL" (методы: SSPI, NTLM).
(Выдаёт именно с такой абракадаброй - что-то, видать, с кодировкой не так)
Если убрать Synchronous:
"
Error <-1>: ldap_bind() failed: Ëîêàëüíàÿ îøèáêà
"
Если же выбрать метод Simple, не убрав пользователя (домен при этом не проставляется), то:
с Use auth. identit. -
"
Error <49>: ldap_simple_bind_s() failed: Íåïðàâèëüíûå ó÷åòíûå äàííûå
"
без -
"
Error <52>: ldap_simple_bind_s() failed: Íåò äàííûõ
"
Если же - SASL или OTHERKIND (домен при этом тоже не проставляется):
"
Error <7>: ldap_bind_s() failed: Ìåòîä ïðîâåðêè ïîäëèííîñòè íå ïîääåðæèâàåòñÿ.
"
SICILY, не убрав пользователя (домен при этом не проставляется):
"
Error <90>: ldap_bind_s() failed: Íåäîñòàòî÷íî ïàìÿòè.
"
MSN (домен при этом тоже не проставляется):
"
Error <86>: ldap_bind_s() failed: Ðåçóëüòàò ïðîâåðêè íåèçâåñòåí.
"
DPA:
без введённого пользователя, но
"
Error <86>: ldap_bind_s() failed: Ðåçóëüòàò ïðîâåðêè íåèçâåñòåí.
"
без Use auth. identit. -
"
Error <85>: ldap_bind_s() failed: Òàéìàóò.
"
с введённым пользователем, но без Use auth. identit. -
"
Error <90>: ldap_bind_s() failed: Íåäîñòàòî÷íî ïàìÿòè.
"
DIGEST:
подрубается либо с введённым пользователем и с Use auth. identit., либо без и без;
с и без -
"
Error <89>: ldap_bind_s() failed: Îøèáêà â ïàðàìåòðå.
"
без и с -
"
Error <82>: ldap_bind_s() failed: Ëîêàëüíàÿ îøèáêà.
"
?

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

Я не совсем понял, что значит: "Можно также вместо ldapsearch попробовать использовать модуль pam_ldap". Естественно, я пробовал использовать, находящийся в составе дистр-а pam_ldap, но как он может сработать, если не срабатывает применённый для проверки связи по ЛДАП ldapsearch?
Неизвестный
15.01.2010, 16:14
общий
P.S. Поменял ключ -w на -W (для ввода пароля) результат запуска скрипта - тот же...
Кстати, на упомянутой вин.машине я пробовал использовать LDAP Browser, но она выдаёт ошибку 49 Invalid credentials (подрубающаяся программа ldp.exe выдаёт такую же ошибку, только если, например, ввести неправильный пароль, или попробовать подрубаться с пользователем, используя метод "Simple"), в независимости от настроек Referrals и Dereference Aliases (но при установке безопасного соединения уже выдаётся ошибка 81 Can't contact LDAP server).

Неизвестный
15.01.2010, 20:22
общий
Ну, во-первых, насчет скрипта. на шелле можно написать все. Другое дело, сколько сил уйдет на реализацию. Я на шелле написал часть системы формирования корпоративного телефонного справочника, который AD читает. Начнем сначала.
Учетка, которую можно использовать для подключения к домену, есть?
Какая версия сервера (винды)? Все, что я говорю проверялось не выше чем на Windows 2003.
Параметр REFERRALS off я уже не помню точно что означает, но без него не работает поиск в AD - авторизация проходит, но поиск всегда неуспешен.
Неизвестный
15.01.2010, 20:46
общий
Подключить машину к домену нельзя (т.е. внести какие-либо изменения на сервере нельзя, а то я уже давным-давно сделал бы авторизацию с помощью winbindd без проблем). Есть простая учётная запись (как и у вех остальных, которые будут авторизоваться в сети), с помощью которой получаю билеты по керберосу.
Приведённые результаты nltest /dsgetdc:domain и ldp.exe недостаточны для определения версии?
Я писал, что пробовал на вин.машине запустить ldapbrowser.exe? Но она не подрубается, как и Линукс - ошибка 49 Invalid credentials (подрубающаяся программа ldp.exe выдаёт такую же ошибку, только если, например, ввести неправильный пароль, или попробовать подрубаться с пользователем, используя метод "Simple"), в независимости от настроек Referrals и Dereference Aliases (но при установке безопасного соединения уже выдаётся ошибка 81 Can't contact LDAP server).

Неизвестный
22.01.2010, 13:10
общий
Если не знаете, что можно сделать с ЛДАП, не могли бы Вы хотя бы привести простейший образец скрипта, который бы обеспечивал следующее при логине:
1. Если в /etc/passwd введённого имени нет, создавал бы беспарольного пользователя (добавив его в /etc/passwd прямо или через useradd) и возвращал бы его данные.
2. Вызывал бы pam_krb5.
3. При этой неудачной аутентификации пользователю давал бы отказ, и если он был создан на шаге 1, то его удалял бы.
4. При удачной авторизации данные передавал бы для стандартной загрузки пользователя (т.е. если он был создан на шаге 1, то производилась бы его первая загрузка с созданием домашней директории с профилем по умолчанию, в противном случае производилась бы стандартная загрузка с собственным профилем).

Кстати, а как интегрировать этот скрипт в /etc/pam.d/login (последний его воспримет, как воспринимает стандартные двоичные pam модули)?
Форма ответа