當 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 utils,因為客戶端不是專家。因此,我希望他們繼續使用典型的 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,則我可以使用該使用者登入任意多次。我認為為此使用兩個變數是無用且違反直覺的。相反,單一變數應該僅在使用者輸入時使用,無論您想將其稱為pwdResetpwdMustChange

答案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) 手冊頁。如果使用者的記錄不包含這些條目中的一項或多項,則不會執行相應的影子檢查。

相關內容