Closed spaceone closed 8 years ago
Try enabling debug
and seeing from your syslog what error is being returned by the KDC in this case. My guess is that AD isn't returning the expected Kerberos error for an expired password. The code may need another case.
syslog/auth doesn't contain anything but I get this from krb5 logging:
2015-11-12T23:01:09 krb5_get_init_creds: loop 1
2015-11-12T23:01:09 KDC send 0 patypes [0/227]
2015-11-12T23:01:09 Trying to find service kdc for realm FOO11.INTRANET flags 0
2015-11-12T23:01:09 error message: Did not find a plugin for service_locator: 2
2015-11-12T23:01:09 configuration file for realm FOO11.INTRANET not found
2015-11-12T23:01:09 searching DNS for realm FOO11.INTRANET udp.kerberos -> 0
2015-11-12T23:01:09 trying to communicate with host win-125in6tla89.foo11.intranet in realm FOO11.INTRANET
2015-11-12T23:01:09 error message: Did not find a plugin for send_to_kdc: 2
2015-11-12T23:01:09 result of trying to talk to realm FOO11.INTRANET = 0
2015-11-12T23:01:09 krb5_get_init_creds: loop 2
2015-11-12T23:01:09 krb5_get_init_creds: processing input
2015-11-12T23:01:09 krb5_get_init_creds: got an error
2015-11-12T23:01:09 krb5_get_init_creds: KRB-ERROR -1765328359
2015-11-12T23:01:09 KDC send 4 patypes
2015-11-12T23:01:09 KDC send PA-DATA type: 19
2015-11-12T23:01:09 KDC send PA-DATA type: 2
2015-11-12T23:01:09 KDC send PA-DATA type: 16
2015-11-12T23:01:09 KDC send PA-DATA type: 15
2015-11-12T23:01:09 krb5_get_init_creds: using ENC-TS with enctype 18
2015-11-12T23:01:09 krb5_get_init_creds: using default_s2k_func
2015-11-12T23:01:09 Trying to find service kdc for realm FOO11.INTRANET flags 0
2015-11-12T23:01:09 error message: Did not find a plugin for service_locator: 2
2015-11-12T23:01:09 configuration file for realm FOO11.INTRANET not found
2015-11-12T23:01:09 searching DNS for realm FOO11.INTRANET udp.kerberos -> 0
2015-11-12T23:01:09 trying to communicate with host win-125in6tla89.foo11.intranet in realm FOO11.INTRANET
2015-11-12T23:01:09 error message: Did not find a plugin for send_to_kdc: 2
2015-11-12T23:01:09 result of trying to talk to realm FOO11.INTRANET = 0
2015-11-12T23:01:09 krb5_get_init_creds: loop 3
2015-11-12T23:01:09 krb5_get_init_creds: processing input
2015-11-12T23:01:09 krb5_get_init_creds: got an error
2015-11-12T23:01:09 krb5_get_init_creds: KRB-ERROR -1765328361
2015-11-12T23:01:09 krb5_get_init_creds: loop 1
2015-11-12T23:01:09 KDC send 0 patypes
2015-11-12T23:01:09 Trying to find service kdc for realm FOO11.INTRANET flags 0
2015-11-12T23:01:09 error message: Did not find a plugin for service_locator: 2
2015-11-12T23:01:09 configuration file for realm FOO11.INTRANET not found
2015-11-12T23:01:09 searching DNS for realm FOO11.INTRANET udp.kerberos -> 0
2015-11-12T23:01:09 trying to communicate with host win-125in6tla89.foo11.intranet in realm FOO11.INTRANET
2015-11-12T23:01:09 error message: Did not find a plugin for send_to_kdc: 2
2015-11-12T23:01:09 result of trying to talk to realm FOO11.INTRANET = 0
2015-11-12T23:01:09 krb5_get_init_creds: loop 2
2015-11-12T23:01:09 krb5_get_init_creds: processing input
2015-11-12T23:01:09 krb5_get_init_creds: got an error
2015-11-12T23:01:09 krb5_get_init_creds: KRB-ERROR -1765328359
2015-11-12T23:01:09 KDC send 4 patypes
2015-11-12T23:01:09 KDC send PA-DATA type: 19
2015-11-12T23:01:09 KDC send PA-DATA type: 2
2015-11-12T23:01:09 KDC send PA-DATA type: 16
2015-11-12T23:01:09 KDC send PA-DATA type: 15
2015-11-12T23:01:09 krb5_get_init_creds: using ENC-TS with enctype 18
2015-11-12T23:01:09 krb5_get_init_creds: using default_s2k_func
2015-11-12T23:01:09 Trying to find service kdc for realm FOO11.INTRANET flags 0
2015-11-12T23:01:09 error message: Did not find a plugin for service_locator: 2
2015-11-12T23:01:09 configuration file for realm FOO11.INTRANET not found
2015-11-12T23:01:09 searching DNS for realm FOO11.INTRANET udp.kerberos -> 0
2015-11-12T23:01:09 trying to communicate with host win-125in6tla89.foo11.intranet in realm FOO11.INTRANET
2015-11-12T23:01:09 error message: Did not find a plugin for send_to_kdc: 2
2015-11-12T23:01:09 result of trying to talk to realm FOO11.INTRANET = 0
2015-11-12T23:01:09 Trying to find service kdc for realm FOO11.INTRANET flags 2
2015-11-12T23:01:09 error message: Did not find a plugin for service_locator: 2
2015-11-12T23:01:09 configuration file for realm FOO11.INTRANET not found
2015-11-12T23:01:09 searching DNS for realm FOO11.INTRANET tcp.kerberos -> 0
2015-11-12T23:01:09 trying to communicate with host win-125in6tla89.foo11.intranet in realm FOO11.INTRANET
2015-11-12T23:01:09 error message: Did not find a plugin for send_to_kdc: 2
2015-11-12T23:01:10 result of trying to talk to realm FOO11.INTRANET = 0
2015-11-12T23:01:10 krb5_get_init_creds: loop 3
2015-11-12T23:01:10 krb5_get_init_creds: processing input
2015-11-12T23:01:10 krb5_get_init_creds: using keyproc
2015-11-12T23:01:10 krb5_get_init_creds: using default_s2k_func
2015-11-12T23:01:10 krb5_get_init_creds: extracting ticket
Your password/account will expire at Thu Jan 1 01:00:00 1970
Sorry about the delay, and the originally incorrect information. I did some more investigation, and it turns out that this is a limitation of Heimdal. Heimdal does not support the krb5_get_init_creds_opt_set_change_password_prompt
API, so there's no way to use defer_pwchange
with Heimdal. I'll fix the documentation to make this clear.
Okay, thank you very much for this information!
I added a bug report/feature request to: https://github.com/heimdal/heimdal/issues/146
Does heimdal also need to do something else e.g. implement another interface? I Implemented this so far so that the 'New password' prompt is not shown anymore if the corresponding flag is set. The problem now is that pam acct_mgmt() returns PAM_SUCCESS instead of PAM_NEW_AUTHTOK_REQD. I had a look in your very nice and clean code, there it seems everything is fine.
Apologies for the delay in replying. I got rather busy over the holidays.
My guess is that Heimdal is returning some other error message in reply to an attempted authentication with an expired password, and that's breaking the logic. Take a look at the case statement at the end of pamk5_password_auth
in auth.c
. Right now, only the error code KRB5KDC_ERR_KEY_EXP
triggers the behavior you want (by causing this function to return PAM_NEW_AUTHTOK_REQD
, which in turn causes pamk5_authenticate
to set the expired flag in the context. This should then be picked up by pam_sm_acct_mgmt
.
It might be useful to just insert some debug logging that prints out the numeric return code from the attempted authentication, and then grep for that in the Kerberos headers to see what constant that corresponds to. The fix may be as simple as adding another constant to that case statement.
If that isn't the problem, another, more irritating possibility is that the authentication context is not being preserved between the pam_sm_authenticate
call and the pam_sm_acct_mgmt
call. If this is the case, you'll be able to see this in debug output. When pam_sm_acct_mgmt
is called, it will attempt to retrieve the existing authentication context. If that fails, it will log a message saying that it's constructing a new one. I'm worried that OpenSSH may not be preserving the PAM context between the auth and account stacks, due to how it implements privilege separation.
Thanks for the answer. With pam_krb5 everything is fine! I just didn't knew that I had to rebuild it after applying my patch to heimdal (https://github.com/heimdal/heimdal/pull/152).
Hi, I am unsure if this is the correct place. I've got a debian system with libpam-heimdal:amd64 4.6-1.22.201403250545 which provides pam_krb5.so.
In my PAM stack I define:
And I still get prompted for the 'New password: ' if the user password has expired when doing authenticate(). The PAM module returns PAM_AUTH_ERR (7) then instead of SUCCESS. acct_mgmt() returns SUCCESS after the failed authentication/password update. It works if the user is a samba4 user but not if the user is a Active Directory user.