Blame pwdstat.c

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