Blame pwdstat.c

Packit 64c699
/*
Packit 64c699
 * Written by Cristian Gafton <gafton@redhat.com>
Packit 64c699
 */
Packit 64c699
Packit 64c699
#include "config.h"
Packit 64c699
Packit 64c699
#include <assert.h>
Packit 64c699
#include <ctype.h>
Packit 64c699
#include <stdio.h>
Packit 64c699
#include <stdlib.h>
Packit 64c699
#include <string.h>
Packit 64c699
Packit 64c699
#include <unistd.h>
Packit 64c699
#include <sys/types.h>
Packit 64c699
Packit 64c699
#include <security/pam_appl.h>
Packit 64c699
#include <security/pam_misc.h>
Packit 64c699
#include <pwd.h>
Packit 64c699
#include <getopt.h>
Packit 64c699
Packit 64c699
char *username = NULL;		/* username we are changing the password for */
Packit 64c699
char *password = NULL;		/* password we are changing the password to */
Packit 64c699
Packit 64c699
/* a dummy coversation function */
Packit 64c699
static int
Packit 64c699
dummy_conv(int num_msg,
Packit 64c699
	   const struct pam_message **msg,
Packit 64c699
	   struct pam_response **resp, void *appdata_ptr)
Packit 64c699
{
Packit 64c699
	int i;
Packit 64c699
	struct pam_response *response = NULL;
Packit 64c699
Packit 64c699
	(void)appdata_ptr;
Packit 64c699
Packit 64c699
	response = malloc(sizeof(struct pam_response) * num_msg);
Packit 64c699
Packit 64c699
	if (response == (struct pam_response *) 0)
Packit 64c699
		return PAM_CONV_ERR;
Packit 64c699
Packit 64c699
	for (i = 0; i < num_msg; i++) {
Packit 64c699
		response[i].resp_retcode = PAM_SUCCESS;
Packit 64c699
Packit 64c699
		switch (msg[i]->msg_style) {
Packit 64c699
		case PAM_PROMPT_ECHO_ON:
Packit 64c699
			response[i].resp = username;
Packit 64c699
			break;
Packit 64c699
Packit 64c699
		case PAM_PROMPT_ECHO_OFF:
Packit 64c699
			response[i].resp = password;
Packit 64c699
			break;
Packit 64c699
Packit 64c699
		case PAM_TEXT_INFO:
Packit 64c699
		case PAM_ERROR_MSG:
Packit 64c699
			/* ignore it, but pam still wants a NULL response... */
Packit 64c699
			response[i].resp = NULL;
Packit 64c699
			break;
Packit 64c699
Packit 64c699
		default:
Packit 64c699
			/* Must be an error of some sort... */
Packit 64c699
			free(response);
Packit 64c699
			return PAM_CONV_ERR;
Packit 64c699
		}
Packit 64c699
	}
Packit 64c699
Packit 64c699
	*resp = response;
Packit 64c699
	return PAM_SUCCESS;
Packit 64c699
}
Packit 64c699
Packit 64c699
Packit 64c699
/* conversation function & corresponding structure */
Packit 64c699
static struct pam_conv conv = {
Packit 64c699
	&dummy_conv,
Packit 64c699
	NULL
Packit 64c699
};
Packit 64c699
Packit 64c699
int
Packit 64c699
main(int argc, char *const argv[])
Packit 64c699
{
Packit 64c699
	int retval;
Packit 64c699
	pam_handle_t *pamh = NULL;
Packit 64c699
Packit 64c699
	/* XXX; expand me:
Packit 64c699
	 *
Packit 64c699
	 * here you should obtains somehow the username and password and
Packit 64c699
	 * set the global variables
Packit 64c699
	 */
Packit 64c699
	(void)argc;
Packit 64c699
	(void)argv;
Packit 64c699
	assert(username != NULL);
Packit 64c699
	assert(password != NULL);
Packit 64c699
Packit 64c699
	retval = pam_start("passwd", username, &conv, &pamh);
Packit 64c699
	while (retval == PAM_SUCCESS) {	/* use loop to avoid goto... */
Packit 64c699
Packit 64c699
		retval = pam_chauthtok(pamh, 0);
Packit 64c699
		if (retval != PAM_SUCCESS)
Packit 64c699
			break;
Packit 64c699
		/* all done */
Packit 64c699
		retval = pam_end(pamh, PAM_SUCCESS);
Packit 64c699
		if (retval != PAM_SUCCESS)
Packit 64c699
			break;
Packit 64c699
		/* quit gracefully */
Packit 64c699
		exit(0);
Packit 64c699
	}
Packit 64c699
Packit 64c699
	if (retval != PAM_SUCCESS)
Packit 64c699
		fprintf(stderr, "changing password: %s\n",
Packit 64c699
			pam_strerror(pamh, retval));
Packit 64c699
Packit 64c699
	if (pamh != NULL) {
Packit 64c699
		(void) pam_end(pamh, PAM_SUCCESS);
Packit 64c699
		pamh = NULL;
Packit 64c699
	}
Packit 64c699
Packit 64c699
	exit(1);
Packit 64c699
}