/* 
 * $Id: passwd.c,v 1.2 1998/12/11 12:03:58 agalat Exp $
 *
 * 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"

#include <pwd.h>

#define PASSWD_MAX_TOKEN                100
#define PASSWD_COMMENT_CHAR             '#'
#define PASSWD_SUFFIX_FILE              "/etc/security/passwd.conf"
#define PASSWD_SERVICE_FORMAT           "passwd%s"
#define PASSWD_SERVICE_DEFAULT          "passwd"
#define PASSWD_FAIL_DELAY               2000000 /* usec delay on failure */
#define PASSWD_KEEP_UPTODATE            01
#define PASSWD_SERVICE_SUFFIX           02
#define PASSWD_GARBLED                  04

#define PASSWD_TRUE                     1
#define PASSWD_FALSE                    0

#define TOK_TYPE_DEFAULT		"DES_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);

    /* 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 if (service_ok(suffix)) 
	tok_type = suffix;
    else 
    {
	fprintf(stderr, "passwd: invalid scheme-suffix \"%s\"\n", suffix);
	exit(1);
    }

    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;
	}
	user = NULL;                         /* can no longer rely on this */

	place = "pniam_create_request";
	res = pniam_create_request (handle, &request);
	if (res != PNIAM_OK)
	{
	    err_descr = "while initializing request";
	    break;
	}
	place = "item_add";
	res = item_add (&(request->input), "AUTHTOK_TYPE", 
			(unsigned char *)tok_type, strlen (tok_type), 
			PNIAM_ITEM_DEFAULT);
	if (res != PNIAM_OK)
	{
	    err_descr = "while trying to add an item";
	    break;
	}
	place = "pniam_change";
	res = 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);
}
