|
Description
|
Problems description: The user's password is reset, and the new password is expired. The first time the user logs in, the user is prompted for the current password, and then new password. The user's password is changed, but the user's cred and shadow fields are not changed. The next time the user logs in, he is prompted for password changing again. Also in syslog's messages, the error messages "Failover to old protocol" and/or "NIS+ server not responsing" are generated.
Customer NIS+ setup: The permissions of the table, passwd.org_dir, is setup so that only the owner of the passwd entry has the write permission to the passwd field, but the owner is not allowed to change the shadow field (to enforce the password aging policy).
Possible Cause. This problem is caused by caching public keys by rpc.nisd. If the user has logged onto the client machine before his password is reset, the keyserv on the client machine caches the user's private key, and rpc.nisd caches the user's public key through a linked list, pointed by a static variable, pkey_tbl. This linked list of public keys are maintained by getpublickeys(). A public key is removed through __getpublickey_flush().
After the user's password is reset, a new pair of public/private keys is generated, and the password is expired. When the user logs onto the box after the password reset, the PAM modules use the old secret key cached on the client machine as the user's credential. rpc.nisd searched its linked list of pub keys pointed by pkey_tbl, and finds the user's old public key. Since the old public key found by nisd matches the old secret key cached on the client's keyserv, rpc.nisd considers the user has a correct RPC credential, and sends back the user's hashed password (instead of "*NP*"). The client authenticates the user, and prompts the user for a new password. Then the client machine uses the user's old credential (old secret key) to authenticate against rpc.nispasswdd (NPD) by calling nispasswd_auth(). The NPD doesn't have the user's public key cached in the linked list pointed by pkey_tbl (NPD and nisd have two different lists because they are two different processes). NPD retrieves the user's public from the disk. The retrieved user's pub key is the new one, and doesn't match the user's old secret key. So NPD rejects the user's authentication request. The client side's PAM receives the error from NPD, and fails over to the old protocol.
In the old protocol, the client side tries to use nis_modify_entry() to modify the user's password, shadow fields and the user's cred entry through nisd using the user's credential, which is still the old credential, and honored by nisd. Depending on the permissions of the table, passwd.org_dir, some of the modification requests might fail, which may result in a different rpc password and/or un-changed shadow field. In either case, the user will have trouble logging into the box, and will request to reset his password again. The cycle goes on.
The client side's PAM module, pam_dhkeys, does verify the user's rpc password through nispasswd_auth() in its pam_sm_chautok(). The funcation call, nispasswd_auth, retrieves the user's new secret key from cred.org_dir, and decrypts it using the user's password. But unfortunately, nispasswd_auth doesn't save the decrypted secret key on the client's keyserv.
The suggested solution is that pam_dhkeys should save the decrypted new secrect key on the keyserv to replace the user's old secret key. In this case, the client PAM modules will use the user's new credential to communicate with nisd. __svcauth_des() has logic to flush the user's pub key from the linked list through __getpublickey_flush() if the cached pub key dosen't work, and reads the pub key from the disk.
|