PAM + pam_ldap + Active Directory

Решил научить vsftpd авторизации пользователей из Windows-домена.

Для этого на dc завел тестовую пользователя ftp1 и группу LAS_ftp, членам которой будет разрешена авторизация на моем FTP-сервере.
(Конечно же, пользователь ftp1 является членом группы LAS_ftp.)

Работать все должно было по следующей схеме:
- vsftpd настраиваем на авторизацию с помощю PAM;
- в PAM для этого приложения говорим использовать pam_ldap;
- для проверки принадлежности пользователя к группе будем использовать модуль pam_require (он у нас правда flagged для x86);
- для создания домашних директорий для этих “виртуальных” пользователей будем использовать модуль pam_mkhomedir;

Вот мой конфиг PAM (приведу вместе с комментами):

LAS ~ # cat /etc/pam.d/vsftpd
#%PAM-1.0

# auth - Аутентификация. Эта подсистема, реализует аутентификацию аппликанта и
#        выяснение полномочий учётной записи. Она предоставляет два примитива:
#
#   Функция pam_authenticate(3) аутентифицирует аппликанта, обычно запрашивая
#   аутентификационный ключ и сравнивая его со значением, хранящимся в базе
#   данных или получаемым от сервера аутентификации.
#
#   Функция pam_setcred(3) устанавливает полномочия учётной записи, такие, как
#   идентификатор пользователя, членство в группах и ограничения на
#   использование ресурсов.

auth       required     pam_ldap.so

# account - Управление учётной записью. Эта подсистема обрабатывает вопросы
#           доступности учетной записи, не связанные с аутентификацией, такие,
#           как ограничения в доступе на основе времени суток или загрузки
#           сервера. Он предоставляет единственный примитив:
#
#   Функция pam_acct_mgmt(3) проверяет, доступна ли запрашиваемая учётная
#   запись.

account    required     pam_ldap.so

# Разрешение на вход только пользователям, входящим в группу LAS_ftp

#account    required    pam_require.so no_case @LAS_ftp



# password - Управление паролем. Эта подсистема используется для изменения
#            ключа аутентификации, связанного с учетной записью, по причине
#            истечения его срока действия или желания пользователя изменить
#            его. Она предоставляет единственный примитив:
#
#   Функция pam_chauthtok(3) изменяет ключ аутентификации, опционально
#   проверяя, что он труден для подбора, не использовался ранее и так далее.

# (Обойдутся без смены пароля!)



# session - Управление сеансом. Эта подсистема отрабатывает задачи, связанные
#           с установлением и закрытием сеанса, такие, как учет входов
#           пользователей. Она предоставляет два примитива:
#
#   Функция pam_open_session(3) выполняет действия, связанные с установлением
#   сеанса: добавление записей в базы данных utmp и wtmp, запуск агента SSH и
#   так далее.
#
#   Функция pam_close_session(3) выполняет действия, связанные с закрытием
#   сеанса: добавление записей в базы данных utmp и wtmp, завершение работы
#   агента SSH и так далее.

# Автоматическое создание домашней директории для новых пользователей
session         required        /lib/security/pam_mkhomedir.so skel=/home/xdomain.local/default.skel umask=0700

Не получилось, настойчиво ругался, что не может авторизовать =(
Nov 2 14:22:21 LAS vsftpd[16378]: [ftp1] FAIL LOGIN: Client "10.10.1.5"

Долго пытался понять, в чем именно ошибка, перечитал немало форумов и мануалов… Решил написать свое маленькое приложение, использующее PAM, чтоб однозначно понять, где именно происходит сбой в процессе авторизации:

#include <security/pam_appl.h>
#include <security/pam_misc.h>
#include <pwd.h>
#include <sys/types.h>
#include <stdio.h>
#define MY_CONFIG "vsftpd"
#define MY_USER "ftp1"

static struct pam_conv conv = { misc_conv, NULL };

main( )
{
  pam_handle_t *pamh;
  int result;

  if ((result = pam_start(MY_CONFIG, MY_USER, &conv, &pamh)) != PAM_SUCCESS)
  {
    fprintf(stderr, "start failed: %d\n", result);
  }
  else if ((result = pam_authenticate(pamh, 0)) != PAM_SUCCESS)
  {
    fprintf(stderr, "authenticate failed: %d\n", result);
  }
  else if ((result = pam_acct_mgmt(pamh, 0)) != PAM_SUCCESS)
  {
    fprintf(stderr, "acct_mgmt failed: %d\n", result);
  }
/*
  else if ((result = pam_open_session(pamh, 0)) != PAM_SUCCESS)
  {
    fprintf(stderr, "open session failed: %d\n", result);
  }
  else if ((result = pam_close_session(pamh, 0)) != PAM_SUCCESS)
  {
    fprintf(stderr, "close session failed: %d\n", result);
  }
*/
  else if ((result = pam_end(pamh, result)) != PAM_SUCCESS)
  {
    fprintf(stderr, "end failed: %d\n", result);
  }
  else
  {
    fprintf(stderr,"Success authenticate!\n");
  };
}

Здесь закомментированы функции начала и окончания сессии пользователя, потому отработают тока модули из PAM-подсистем auth и account.
В конфиге PAM для vsftpd закомментирован вызов pam_require, потому на принадлежность группе пока пользователя не проверяем.

1) Компилим приложение (gcc ./chkpam.c -lpam -lpam_misc -o chkpam), запускаем, вводим пароль – все хорошо, аутентификация пройдена! (при неправильном пароле – аутентификация будет провалена, из чего я предпологаю, что pam_ldap отрабатывает нормально)

LAS ~ # ./chkpam
...
Password:
...
Success authenticate!

2) Раскомментируем вызов pam_require (в /etc/pam.d/vsftpd) и заново запустим наше приложение – все плохо (((
PAM у меня собран с debug, так что, вот что он нам говорит:

LAS ~ # ./chkpam
...
[pam_handlers.c:_pam_init_handlers(342)] _pam_init_handlers called
[pam_dispatch.c:_pam_dispatch_aux(106)] passing control to module...
[pam_item.c:pam_get_user(280)] called.
[pam_data.c:pam_get_data(123)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_data.c:pam_set_data(70)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_item.c:pam_get_item(179)] called.
[pam_item.c:pam_get_item(179)] called.
[misc_conv.c:misc_conv(279)] allocating empty response structure array.
[misc_conv.c:misc_conv(288)] entering conversation function.
[misc_conv.c:read_string(136)] called with echo='OFF', prompt='Password: '.
Password:
[misc_conv.c:read_string(203)] we got some user input
[pam_item.c:pam_set_item(31)] called
[pam_item.c:pam_get_item(179)] called.
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Success
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-1 cached_retval=0 retval=0
[pam_item.c:pam_set_item(31)] called
[pam_item.c:pam_set_item(31)] called
[pam_delay.c:_pam_await_timer(90)] waiting?...
[pam_delay.c:_pam_compute_delay(76)] random number: base=0 -> ans=0

[pam_delay.c:_pam_reset_timer(27)] setting pamh->fail_delay.set to FALSE
[pam_delay.c:_pam_await_timer(126)] waiting done
[pam_auth.c:pam_authenticate(39)] pam_authenticate exit
[pam_account.c:pam_acct_mgmt(11)] called
[pam_handlers.c:_pam_init_handlers(342)] _pam_init_handlers called
[pam_dispatch.c:_pam_dispatch_aux(106)] passing control to module...
[pam_item.c:pam_get_item(179)] called.
[pam_data.c:pam_get_data(123)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_item.c:pam_get_user(280)] called.
[pam_data.c:pam_get_data(123)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Success
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-1 cached_retval=0 retval=0
[pam_dispatch.c:_pam_dispatch_aux(106)] passing control to module...
[pam_item.c:pam_get_user(280)] called.
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Authentication failure
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-3 cached_retval=7 retval=7
acct_mgmt failed: 7

ну да бог с ним, с этим flagged модулем, комментируем его обратно и идем дальше!

2) Раскомментируем функции начала и окончания сессии для нашего пользователя, скомпилим и заново запустим наше приложение – все снова плохо (((

LAS ~ # ./chkpam
...
Password:
[misc_conv.c:read_string(203)] we got some user input
[pam_item.c:pam_set_item(31)] called
[pam_item.c:pam_get_item(179)] called.
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Success
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-1 cached_retval=0 retval=0
[pam_item.c:pam_set_item(31)] called
[pam_item.c:pam_set_item(31)] called
[pam_delay.c:_pam_await_timer(90)] waiting?...
[pam_delay.c:_pam_compute_delay(76)] random number: base=0 -> ans=0

[pam_delay.c:_pam_reset_timer(27)] setting pamh->fail_delay.set to FALSE
[pam_delay.c:_pam_await_timer(126)] waiting done
[pam_auth.c:pam_authenticate(39)] pam_authenticate exit
[pam_account.c:pam_acct_mgmt(11)] called
[pam_handlers.c:_pam_init_handlers(342)] _pam_init_handlers called
[pam_dispatch.c:_pam_dispatch_aux(106)] passing control to module...
[pam_item.c:pam_get_item(179)] called.
[pam_data.c:pam_get_data(123)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_item.c:pam_get_user(280)] called.
[pam_data.c:pam_get_data(123)] called
[pam_data.c:_pam_locate_data(46)] called
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Success
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-1 cached_retval=0 retval=0
[pam_session.c:pam_open_session(15)] called
[pam_handlers.c:_pam_init_handlers(342)] _pam_init_handlers called
[pam_dispatch.c:_pam_dispatch_aux(106)] passing control to module...
[pam_item.c:pam_get_item(179)] called.
[pam_item.c:pam_get_item(196)] returning user=ftp1
[pam_modutil_getpwnam.c:pam_modutil_getpwnam(112)] pwd structure took 1052 bytes or so of memory
[pam_mkhomedir.c:pam_sm_open_session(219)] couldn't identify user ftp1
[pam_dispatch.c:_pam_dispatch_aux(114)] module returned: Insufficient credentials to access authentication data
[pam_dispatch.c:_pam_dispatch_aux(198)] use_cached_chain=0 action=-3 cached_retval=8 retval=8
open session failed: 8

хм... ну ладно с flagged pam_require, но ведь pam_mkhomedir собирается в базовом (стабильном) пакете pam, что с ним может быть не так?
Конечно же я комментировал лишнее и вызывал модуль pam_mkhomedir с опциями по умолчанию… (стандартный umask и путь до skel) не помогло – результат был абсолютно идентичным!

Люди, помогите чем модежете, уж больно хочеться разобраться где затык?!!

/

bizon написал(а):
хм... ну ладно с flagged pam_require, но ведь pam_mkhomedir собирается в базовом (стабильном) пакете pam, что с ним может быть не так?
Конечно же я комментировал лишнее и вызывал модуль pam_mkhomedir с опциями по умолчанию… (стандартный umask и путь до skel) не помогло – результат был абсолютно идентичным!

Люди, помогите чем модежете, уж больно хочеться разобраться где затык?!!

Рано тебя в глухие дебри занесло.
Думается мне, конерь проблемы практически на поверхности.

Система (на которой стоит FTP-сервер) какой механизм авторизации использует?
FTP-пользователи относительно системы скорее всего вирутальные!
Какой может быть домашний каталог (создаваемый как бы не стандартными системными инструментами) у вирутального (не существующего в системе) пользователя?!?

Как у тебя приземляется FTP-сервер (с виртуальными пользователями) для доступа к файловой системе (ограничивается для реальных системных пользователей)?

:wq
--
Live free or die

Anarchist

Anarchist написал(а):
Система (на которой стоит FTP-сервер) какой механизм авторизации использует?

PAM

Anarchist написал(а):
FTP-пользователи относительно системы скорее всего вирутальные!

конешно виртуальные

Anarchist написал(а):
Какой может быть домашний каталог (создаваемый как бы не стандартными системными инструментами) у вирутального (не существующего в системе) пользователя?!?

Как у тебя приземляется FTP-сервер (с виртуальными пользователями) для доступа к файловой системе (ограничивается для реальных системных пользователей)?

FTP дает доступ виртуальным пользователям к локальным папкам и файлоам от имени урезанного в правах пользователя, pam_mkhomedir используется только для создания им стартового каталога.

Примеров использования этого модуля для vsfpd с "витруальными" пользователями полно в сети, вот один из них:
http://www.propheta.ru/2008/03/vsftpd-ldap.html

Весьма вероятно, что vsftpd более гибко работает с PAM, чем моя програмулина =) сейчас еще раз поковыряю vsftpd.conf на предмет локального (ограниченного в правах доступа) пользователя (при закомментированном pam_require).

хм, действительно в конфиге я

хм, действительно в конфиге я забыл поставить опцию virtual_use_local_privs=YES, однако, ее добавление также не помогло =(

Все попытки залогиниться тщетны...

LAS etc # tail -n 6 /var/log/vsftpd/log
Nov 16 16:00:08 LAS vsftpd[6817]: pam_mkhomedir(vsftpd:session): User unknown.
Nov 16 16:00:08 LAS vsftpd[6817]: [ftp1] FAIL LOGIN: Client "10.10.1.5"
Nov 16 16:00:22 LAS vsftpd[6819]: pam_mkhomedir(vsftpd:session): User unknown.
Nov 16 16:00:22 LAS vsftpd[6819]: [ftp1] FAIL LOGIN: Client "10.10.1.5"
Nov 16 16:02:14 LAS vsftpd[6821]: pam_mkhomedir(vsftpd:session): User unknown.
Nov 16 16:02:14 LAS vsftpd[6821]: [ftp1] FAIL LOGIN: Client "10.10.1.5"

Вот мой конфиг vsftpd:

LAS etc # cat /etc/vsftpd/vsftpd.conf | grep -v "#"
listen=YES
listen_ipv6=NO

ftpd_banner=Welcome to xDomain FTP service.

pasv_enable=NO

port_enable=YES

connect_from_port_20=YES

syslog_enable=YES

write_enable=YES

dirmessage_enable=YES

anonymous_enable=NO

local_enable=YES

pam_service_name=vsftpd

session_support=YES

chroot_local_user=YES

virtual_use_local_privs=YES

hide_ids=YES

Я вот тока nss_ldap не ставил, как в указанном мною примере, потому как его использование я встретил тока у этого автора... (а разлчных примеров конфигрурирования vsftpd я повидал более нескольких дестков...) Вот терь думаю, что может зря этого не сделал.

.

bizon написал(а):
хм, действительно в конфиге я забыл поставить опцию virtual_use_local_privs=YES, однако, ее добавление также не помогло =(

Одну опечатку обнаружили :)

bizon написал(а):
Я вот тока nss_ldap не ставил, как в указанном мною примере, потому как его использование я встретил тока у этого автора... (а разлчных примеров конфигрурирования vsftpd я повидал более нескольких дестков...) Вот терь думаю, что может зря этого не сделал.

Несколько десятков примеров конфигурирования подходящих для втоей задачи???

nss_ldap является необходимым и органическим дополнением к pam_ldap. До того, что (в нормальном случае, а не в цитированном тобой примере) они используют один и тот же конфигурационный файл.

А ещё заслуживает рассмотрения вопрос структуры дерева LDAP и набора атрибутов пользователя в оном дереве.

:wq
--
Live free or die

/

bizon написал(а):
Примеров использования этого модуля для vsfpd с "витруальными" пользователями полно в сети, вот один из них:
http://www.propheta.ru/2008/03/vsftpd-ldap.html

С практической точки зрения к подобным примерам необходимо относится с изрядной долей осторожности.

Сужу по личному опыту на примере задачи перевода системной авторизации на использование базы пользователей в OpenLDAP.

:wq
--
Live free or die

Задачу решил. Правы были те

Задачу решил. Правы были те скептики, которые говорили, что вся проблема в продуктах MS.

Для того, чтоб Linux ldap-утилиты нормально отрабатывали, нужно расширить схему на DC Windows.

Для Windows 2000 и 2003 (не R2) нужны Сервисы Microsoft Windows для UNIX (Microsoft Windows Services for UNIX, SFU)
(подробнее тут и тут.)

Для Windows 2003 R2 старше эти компоненты уже частично включены в систему, из них нам нужна Subsystem for UNIX-based Applications (SUA)
(подробнее тут.)

Угу, все так . причем здесь

Угу, все так .
причем здесь MS, слабо понятно, ибо лто то все равно должен маппить юзеров из SSIDов в id.
ссылки как бы оч. быстро находятся на самом течнете

http://technet.microsoft.com/en-us/magazine/2008.12.linux.aspx - как введение
и если совсем чуть поискать , то там же еще куча статей по этой теме от мелкомягких
находится сдесь

Compute:
Bosch M2.8.1 -> custom Bosch M2.8.3 clone from Russia.
Speed about 260 km,Ram 2 pers.,HDD - 70 kg,210 FLOPS ;)

Да, с пользователями все

Да, с пользователями все норм, аутентификацию можно наладить и так...

Зато как только дело доходит до групп, и выяснения членства в них - все гораздо хуже (((

На течнете действительно есть вагон и маленькая тележка статей по поводу совмещения MS и Linux продуктов, только как правило админы начинают изучать доки не со стороны MS продуктов, а со стороны LDAP, и тут в Рунете оказывается на удивленее мало толковых статей, которые бы посоветовали поближе познакомиться с MS SFU и его потомками...

.

bizon написал(а):
только как правило админы начинают изучать доки не со стороны MS продуктов, а со стороны LDAP

1. И правильно делают!
2. Лично я бы с большим интересом почитал результаты допроса мелкомягких разработчиков на предмет: почему некоторое время назад категорически не рекомендовалось менять (как минимум в сторону увеличения) число возвращаемых AD записей и как с этим обстоит сейчас?

bizon написал(а):
и тут в Рунете оказывается на удивленее мало толковых статей, которые бы посоветовали поближе познакомиться с MS SFU и его потомками...

Проприетарщину надо мочить, а не изучать!

:wq
--
Live free or die

Настройки просмотра комментариев

Выберите нужный метод показа комментариев и нажмите "Сохранить установки".