#include "kadm_locl.h"

RCSID("$Id: new_pwd.c,v 1.3 1996/05/29 23:24:04 assar Exp $");

#ifdef NOENCRYPTION
#define read_long_pw_string placebo_read_pw_string
#else
#define read_long_pw_string des_read_pw_string
#endif

static char *
check_pw (char *pword)
{
    if (strlen(pword) == 0)
	return "Null passwords are not allowed - Please enter a longer password.";
    
    if (strlen(pword) < MIN_KPW_LEN)
	return "Password is to short - Please enter a longer password.";
    
    /* Don't allow all lower case passwords regardless of length */
    {
	char *t;
	for (t = pword; *t && islower(*t); t++)
	    ;
	if (*t == 0)
	    return "Please don't use an all-lower case password.\n\tUnusual capitalization, delimiter characters or digits are suggested.";
    }

    return NULL;
}

int
get_pw_new_pwd(char *pword, int pwlen, char *name, char *inst,
	       char *realm, int print_realm)
{
    char ppromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
    char npromp[40+ANAME_SZ+INST_SZ+REALM_SZ]; /* for the password prompt */
    
    char local_realm[REALM_SZ];
    int status;
    char *expl;
    
    /*
     * We don't care about failure; this is to determine whether or
     * not to print the realm in the prompt for a new password. 
     */
    (void) krb_get_lrealm(local_realm, 1);
    
    if (strcmp(local_realm, realm))
	print_realm++;
    
    (void) sprintf(ppromp,"Old password for %s%s%s%s%s:",
		   name, *inst ? "." : "", inst,
		   print_realm ? "@" : "", print_realm ? realm : "");
    if (read_long_pw_string(pword, pwlen-1, ppromp, 0)) {
	fprintf(stderr, "Error reading old password.\n");
	return -1;
    }

    if ((status = krb_get_pw_in_tkt(name, inst, realm, PWSERV_NAME, 
				    KADM_SINST, 1, pword)) != KSUCCESS) {
	if (status == INTK_BADPW) {
	    printf("Incorrect old password.\n");
	    return -1;
	}
	else {
	    fprintf(stderr, "Kerberos error: %s\n", krb_err_txt[status]);
	    return -1;
	}
    }
    memset(pword, 0, pwlen);
    do {
	char verify[MAX_KPW_LEN];
	(void) sprintf(npromp,"New Password for %s%s%s%s%s:",
		       name, *inst ? "." : "", inst,
		       print_realm ? "@" : "", print_realm ? realm : "");
	if (read_long_pw_string(pword, pwlen-1, npromp, 0)) {
	    fprintf(stderr,
		    "Error reading new password, password unchanged.\n");
	    return -1;
        }
	expl = check_pw (pword);
	if (expl) {
	    printf("\n\t%s\n\n", expl);
	    continue;
	}
	/* Now we got an ok password, verify it. */
	(void) sprintf(npromp,"Verifying New Password for %s%s%s%s%s:",
		       name, *inst ? "." : "", inst,
		       print_realm ? "@" : "", print_realm ? realm : "");
	if (read_long_pw_string(verify, MAX_KPW_LEN-1, npromp, 0)) {
	    fprintf(stderr,
		    "Error reading new password, password unchanged.\n");
	    return -1;
        }
	if (strcmp(pword, verify) != 0) {
	    printf("Verify failure - try again\n");
	    expl = "";		/* continue */
	}
    } while (expl);
    return 0;
}
