/* 
 * $Id: passwd.c,v 1.3 1999/11/02 09:41:54 agalat Rel $
 *
 * passwd.c
 *
 * Written for Linux-PAM by Andrew G. Morgan <morgan@linux.kernel.org>
 *
 */

#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#include <pniam.h>

#include "../../common/include/config.h"
#include "../../common/include/passwd_indep.h"

#include "../include/get_pniam_err.h"
#include "../include/com_lib.h"

#define PASSWD_FAIL_DELAY               2000000 /* usec delay on failure */
#define PASSWD_KEEP_UPTODATE            01
#define PASSWD_SERVICE_SUFFIX           02

#define TOK_TYPE_DEFAULT		"PLAIN_PASSWORD"

/* ------- the application itself -------- */

void main(int argc, const char **argv)
{
    const char *tok_type, *user, *suffix;
    int passwd_flags;
    struct pniam_handle *handle = NULL;
    pniam_request_t *request = NULL;
    pniam_result_t res;
    char *place, *err_descr;

    /* obtain user's specific request */

    passwd_flags = parse_pass_args(argc, argv, &suffix, &user);

    if (passwd_flags & PASSWD_KEEP_UPTODATE) {
        fprintf (stderr, "passwd: -k: this option is not supported\n");
        exit (1);
    }
    /* obtain the correct name for the service - check suffix is in list */
    if (suffix == NULL || !(passwd_flags & PASSWD_SERVICE_SUFFIX)) 
        tok_type = TOK_TYPE_DEFAULT;
    else
        tok_type = suffix;

    if (user == NULL) 
	if ((user = getlogin()) == NULL) {
	    fprintf(stderr, "passwd: cannot retrieve user's name\n");
	    exit(1);
	}

    /* here we know whose passwords are to be changed */

    do {
        place = "pniam_start";
        res = pniam_start ("passwd", &handle);
        if (res != PNIAM_OK) {
            err_descr = "while initializing handle";
            break;
        }

        place = "pniam_create_request";
        res = pniam_create_request (handle, &request);
        if (res != PNIAM_OK) {
            err_descr = "while initializing request";
            break;
        }
        place = "item_add";
        res = pniam_item_add2list (&(request->input), "USER", 
			(unsigned char *)user, strlen (user), 
			PNIAM_ITEM_DEFAULT);
        if (res != PNIAM_OK) {
            err_descr = "while trying to add an item";
            break;
        }
        res = pniam_item_add2list (&(request->input), "CHANGE_ITEM", 
			(unsigned char *)tok_type, strlen (tok_type), 
			PNIAM_ITEM_DEFAULT);
        if (res != PNIAM_OK) {
            err_descr = "while trying to add an item";
            break;
        }
        user = NULL;                         /* can no longer rely on this */
        place = "pniam_change";
        res = pas_change (handle, request);
        if (res != PNIAM_OK) {
            err_descr = "while updating authentication tokens";
            break;
        }

        pniam_destroy_request (handle, request, PNIAM_PARENT);
        pniam_end (handle);
        /* quit gracefully */

        fprintf(stderr,
            "passwd: Authentication tokens updated successfully\n");

        exit(0);
    }while (0);

    if (handle != NULL) {
        if (request != NULL)
            pniam_destroy_request (handle, request, PNIAM_PARENT);
        pniam_end (handle);
    }

    if (res != PNIAM_OK)
        fprintf(stderr, "%s: %s %s\n", place, get_pniam_err (res), 
							err_descr);
    exit(1);
}
