当 pwdReset = TRUE 时,无法使用 PAM 验证 LDAP 客户端

当 pwdReset = TRUE 时,无法使用 PAM 验证 LDAP 客户端

我搜索了大量网站和教程,但找不到我的问题的答案。

我在 OpenSUSE 12.3 机器上设置了 OpenLDAP 2.4,并设置了密码策略覆盖。客户端是安装了 libnss-ldap 和 libpam-ldap 软件包的 Linux Mint 17.1 机器。客户端和服务器配置为使用自签名证书的 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

此消息告诉我用户凭据不再有效,这是合理的,因为我重置了他的密码,但并未提示用户需要更改密码或任何其他信息。此外,我想阻止使用 ldappasswd 等 openldap 实用程序,因为客户不是专家。因此,我希望他们继续使用典型的 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 服务器上的策略不一定等同于操作系统内的策略。您似乎正在描绘一个框架,您可以在其中设置此覆盖属性,并且操作系统意识到需要更改密码,但正如您所见,它的工作方式并非如此。

要在操作系统中触发提示,会计模块(通常是 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) 手册页中。如果用户的记录不包含这些条目中的一个或多个,则不会执行相应的影子检查。

相关内容