/* UNIX like PASSWD program. Kees Lemmens; Aug '92

   With this program you can change the password entry in the /etc/passwd
   file. Of course it is important to use the same encryption in this
   routine as in the getty program or else you'll won't get in !

   Version 1.1 : Sept 1993

	Uid 0 doesn't have to enter old password anymore.

   Any questions or suggestions about this program can be send to:
   lemmens@dv.twi.tudelft.nl
*/

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <string.h>
#include <pwd.h>
#include "ux_misc.h"

char *tmp_file = TMPPW;
char *pwd_file = PASSWD;

void pw_write(char *pwd,char *pwline,FILE *tmp)
{	char *hlp=strchr(pwline,':')+1;

	encrypt(pwd);
	fwrite(pwline,1,hlp-pwline,tmp);
	fwrite(pwd,1,strlen(pwd),tmp);
	fputs(strchr(hlp,':'),tmp);
}

void cancel(FILE *tmp)
{	endpwent();
	fclose(tmp);
	remove(tmp_file);
	exit(1);
}

void main(int argc, char *argv[])
{	char *name,*hlp,pwd[50],pw2[50];
	struct passwd *pwent;
	FILE *tmp;
	
	if((tmp=fopen(tmp_file,"w+")) == NULL)		/* creat file */
	{	tmp_file="c:\\etc\\passwd.nw";
		pwd_file="c:\\etc\\passwd";
		if((tmp=fopen(tmp_file,"w+")) == NULL)
		{	puts("Can't open outputfile");
			exit(1);
		}
	}

	name = argc>1 ? argv[1] : getenv("LOGNAME");		
	if(name == NULL)
	{	puts("No username supplied");
		exit(1);
	}
	if((hlp=strchr(name,'\n')) != NULL) *hlp='\0';

	while(1)
	{	if((pwent=getpwent()) == NULL)
		{	puts("Loginname not found");
			cancel(tmp);
		}
		if(! strncmp(name,pwd_line,strlen(name)) )
			break;			/* login name found */
		fputs(pwd_line,tmp);
	}

	if(Pgetuid() != 0)	/* skip this part for root */
	{	Put("\r\nOld password: ");
		Get(pwd,40,0);

		if(check_pw(pwd,pwent) < 0)
		{	puts("Invalid password");
			cancel(tmp);
		}
	}

	Put("\r\nNew password: ");
	Get(pwd,40,0);
	Put("\r\nReenter new password: ");
	Get(pw2,40,0);
	
	if(strcmp(pwd,pw2))
	{ 	puts(" Both passwords do not match");
		cancel(tmp);
	}
	pw_write(pwd,pwd_line,tmp);	/* write new entry */

	while(getpwent() != NULL)
		fputs(pwd_line,tmp);		/* copy rest of passwdfile */

	fclose(tmp);
	endpwent();
	
	Put("\r\n"); /* delay until file is really closed */

	if(remove(pwd_file) != 0)
	{	puts("Can't write new passwd file !");
		remove(tmp_file);
	}
	else
		rename(tmp_file,pwd_file);
	exit(0);
}
