#include <config.h>

#ifdef PAM

#include "rcsid.h"
RCSID("$Id: pam_pass.c,v 1.3 1998/01/29 23:22:36 marekm Exp $")

/*
 * Change the user's password using PAM.  Requires libpam and libpam_misc
 * (for misc_conv).  Note: libpam_misc is probably Linux-PAM specific,
 * so you may have to port it if you want to use this code on non-Linux
 * systems with PAM (such as Solaris 2.6).  --marekm
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <security/pam_appl.h>
#include <security/pam_misc.h>

static const struct pam_conv conv = {
	misc_conv,
	NULL
};

void
do_pam_passwd(const char *user, int silent, int change_expired)
{
	pam_handle_t *pamh = NULL;
	int flags = 0, ret;

	if (silent)
		flags |= PAM_SILENT;
	if (change_expired)
		flags |= PAM_CHANGE_EXPIRED_AUTHTOK;

	ret = pam_start("passwd", user, &conv, &pamh);
	if (ret != PAM_SUCCESS)
		goto failure;

	ret = pam_chauthtok(pamh, flags);
	if (ret != PAM_SUCCESS) {
		pam_end(pamh, ret);
		goto failure;
	}

	ret = pam_end(pamh, PAM_SUCCESS);
	if (ret != PAM_SUCCESS) {
failure:
#ifdef PAM_STRERROR_NEEDS_TWO_ARGS  /* Linux-PAM 0.59+ */
		fprintf(stderr, "passwd: %s\n", pam_strerror(pamh, ret));
#else
		fprintf(stderr, "passwd: %s\n", pam_strerror(ret));
#endif
		exit(10);  /* XXX - should conform to the other passwd exit codes */
	}
}
#else /* !PAM */
extern int errno;  /* warning: ANSI C forbids an empty source file */
#endif /* !PAM */
