Невозможно аутентифицировать клиента LDAP с помощью PAM, когда pwdReset = TRUE

Невозможно аутентифицировать клиента LDAP с помощью PAM, когда pwdReset = TRUE

Я просмотрел множество сайтов и руководств, но так и не смог найти ответ на свою проблему.

Я настроил OpenLDAP 2.4 на машине OpenSUSE 12.3 с наложением политики паролей. Клиент — машина Linux Mint 17.1 с установленными пакетами libnss-ldap и libpam-ldap. Клиент и сервер настроены на использование TLS с самоподписанными сертификатами (сервер работает как CA и подписывает свой собственный сертификат). Все работает отлично, пока я не добавляю атрибут pwdReset: TRUEпользователю.

Мое намерение состоит в том, чтобызаставить пользователя сменить пароль при следующем входе в систему. Однако после установки этого атрибута пользователь больше не может пройти аутентификацию: если я попытаюсь выполнить 'su' (или войти с помощью) пользователя, то получу ошибку "Ошибка аутентификации". Кроме того, в системном журнале отображаются следующие сообщения:

Mar 4 07:27:11 client-desktop nslcd[3198]: [90cde7] <authc="johndoe"> ldap_result() failed: Insufficient access: Operations are restricted to bind/unbind/abandon/StartTLS/modify password
Mar 4 07:27:11 client-desktop nslcd[3198]: [dcc233] <authc="johndoe"> cn=John Doe,ou=people,cd=domain,dc=com: lookup failed: Invalid credentials

Это сообщение говорит мне, что учетные данные пользователя больше не действительны, что разумно, так как я сбрасываю его пароль, но пользователю не предлагается изменить свой пароль или что-то еще. Кроме того, я хочу предотвратить использование утилит openldap, таких как ldappasswd, поскольку клиенты не являются экспертами. Поэтому я хочу, чтобы они продолжали использовать типичную команду passwd для изменения своих собственных паролей. По крайней мере, это возможно, когда pwdReset не установлен. Кроме того, я могу получить такое поведение, установив атрибут shadowLastChangeна 0, но я хотел бы сделать все с помощью политик паролей, так как я также пытаюсь принудительно использовать пароли длиной не менее 8 символов. Кстати, эта функция работает отлично.

Это отрывок из моего базового DN, чтобы вы могли проверить, не упустил ли я чего-то. Обратите внимание, что pwdResetустановлено значение TRUE для пользователя, а pwdMustChangeпеременная установлена ​​на TRUE в самой политике.

# John Doe, people, domain.com
dn: cn=John Doe,ou=people,dc=domain,dc=com
cn: John Doe
sn: Doe
objectClass: top
objectClass: person
objectClass: posixAccount
objectClass: shadowAccount
uid: johndoe
uidNumber: 1003
gidNumber: 1000
homeDirectory: /home/johndoe
loginShell: /bin/bash
userPassword: e1NTSEF9VWFSMDVsSGNIWFMxcnJ5VzBtaWRkOHFmTDE1ai9RYlQ=
pwdReset: TRUE # This attribute only appears if I explicitly request it 

# policies, domain.com
dn: ou=policies,dc=domain,dc=com
objectClass: top
objectClass: organizationalUnit
ou: policies

(Следующие атрибуты относятся к cn=default,ou=policies, но по какой-то причине они не отображаются, пока я не напишу что-нибудь здесь)

pwdInHistory: 3
pwdLockout: TRUE
pwdMaxFailure: 3
pwdLockoutDuration: 30
pwdMustChange: TRUE
pwdSafeModify: FALSE
pwdAllowUserChange: TRUE
pwdFailureCountInterval: 0
pwdGraceAuthNLimit: 0

А это конфигурация моего бэкэнда и политик паролей:

# {1}hdb, config
dn: olcDatabase={1}hdb,cn=config
objectClass: olcDatabaseConfig
objectClass: olcHdbConfig
olcDatabase: {1}hdb
olcDbDirectory: /var/lib/ldap
olcSuffix: dc=domain,dc=com
olcAccess: {0}to attrs=userPassword by self write by * auth
olcAccess: {1}to attrs=shadowLastChange by self write by * read
olcAccess: {2}to attrs=userPKCS12 by self read by * none
olcAccess: {3}to * by * read
olcRootDN: cn=admin,dc=domain,dc=com
olcRootPW: {SSHA}############## omited
olcDbCacheSize: 10000
olcDbCheckpoint: 1024 5
olcDbConfig: {0}set_cachesize 0 15000000 1
olcDbConfig: {1}set_lg_regionmax 262144
olcDbConfig: {2}set_lg_bsize 2097152
olcDbConfig: {3}set_flags DB_LOG_AUTOREMOVE
olcDbConfig: {4}set_lk_max_locks 30000
olcDbConfig: {5}set_lk_max_objects 30000
olcDbIDLcacheSize: 30000
olcDbIndex: objectclass eq
[...more indexes...]

# {0}ppolicy, {1}hdb, config
dn: olcOverlay={0}ppolicy,olcDatabase={1}hdb,cn=config
objectClass: top
objectClass: olcConfig
objectClass: olcOverlayConfig
objectClass: olcPPolicyConfig
olcOverlay: {0}ppolicy
olcPPolicyDefault: cn=default,ou=policies,dc=domain,dc=com
olcPPolicyHashCleartext: TRUE

(Следующие два атрибута также относятся к {0}ppolicy)

olcPPolicyUseLockout: FALSE 
olcPPolicyForwardUpdates: FALSE

Надеюсь, кто-нибудь сможет пролить свет на это. Любая помощь будет крайне признательна!

С уважением

Редактировать:

Я внес некоторые изменения в политику по умолчанию, чтобы понять, что мешало аутентификации пользователя. Я понял, что если pwdMustChangeустановлено значение TRUE и pwdResetтакже установлено значение TRUE (этот параметр при записи пользователя), то аутентификация пользователя завершается ошибкой 'su: Ошибка аутентификации'. Однако если установлено pwdResetзначение TRUE и pwdMustChangeзначение FALSE, то я вхожу в систему столько раз, сколько хочу с этим пользователем. Я думаю, что наличие двух переменных для этого бесполезно и нелогично. Вместо этого следует использовать одну переменную только при записи пользователя, как бы вы ее ни называли, pwdResetили pwdMustChange.

решение1

Политики на сервере LDAP не обязательно соответствуют политикам в ОС. Вы, кажется, представляете себе фреймворк, в котором вы устанавливаете это свойство overflay иОперационные системыосознает необходимость смены пароля, но, как вы видите, это не так работает.

Чтобы вызвать запрос в операционной системе, модуль учета (обычно PAM) должен заметить это состояние. Наложение политики паролей OpenLDAP не является стандартом POSIX. В отличие от того, что происходит, когда вы настраиваете свойства shadowпользователя для установки политики, pam_unixне имеет сведений об этих атрибутах, которые вы устанавливаете. Того же самого нельзя сказать о самом сервере OpenLDAP. Это приводит к блокировке пользователя, поскольку пользователь не может пройти аутентификацию на сервере Linux и не имеет достаточной информации о LDAP (как вы сами заметили) для работы с сервером LDAP напрямую для изменения своего пароля.

Если вы хотите запустить запросы на смену пароля в ОС, это не тот инструмент для работы. Я бы лично рекомендовал вам ознакомиться с соответствующими shadowатрибутами, сохранить их в LDAP, если ими нужно управлять централизованно, и использовать их для запуска нужного вам поведения.

Из pam_unix(8)страницы руководства:

Компонент учетной записи выполняет задачу установления статуса учетной записи и пароля пользователя на основе следующих теневых элементов: expire, last_change, max_change, min_change, warn_change. В последнем случае он может предложить пользователю совет по смене пароля или, посредством возврата PAM_AUTHTOKEN_REQD, отложить предоставление пользователю услуги до тех пор, пока он не установит новый пароль. Перечисленные выше записи документированы на странице руководства shadow(5). Если запись пользователя не содержит одну или несколько из этих записей, соответствующая теневая проверка не выполняется.

Связанный контент