|
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 |
}
|