package auth

import "github.com/msteinert/pam"

// Authenticate verifies a username/password against the nadir PAM service.
//
// Both stacks are run. Authenticate checks the password; AcctMgmt runs the
// `account` stack (pam_unix), which is what enforces account and password
// expiry - the shadow sp_expire/sp_max fields an admin sets with `chage -E` or
// `usermod --expiredate` to disable an account without deleting it. Skipping it
// would let a disabled account keep logging in here long after ssh and console
// reject it.
func Authenticate(username, password string) error {
	t, err := pam.StartFunc(PAMService, username, func(s pam.Style, msg string) (string, error) {
		if s == pam.PromptEchoOff {
			return password, nil
		}
		return "", nil
	})

	if err != nil {
		return err
	}
	// No explicit close: msteinert/pam ends the transaction via a finalizer.

	if err := t.Authenticate(0); err != nil {
		return err
	}
	return t.AcctMgmt(0)
}
